精华内容
下载资源
问答
  • 根号n段归并排序算法时间复杂度分析过程: 1.合并 根号n向下取整 段子数组使用是自底向上两两归并策略 2.根号n段归并排序算法时间复杂度的数学推导
  • 时间复杂度根号n的素数判定算法

    千次阅读 2020-01-21 13:21:47
    #include<...int isPrime(int n) { int i; for (i = 2; i*i <= n&&n%i; i++); if (n < 2 || i*i <= n) return 0; return 1; } int main() { int i; for (i = -50; i < 50...
    #include<stdio.h>
    
    int isPrime(int n)
    {
    	int i;
    	for (i = 2; i*i <= n&&n%i; i++);
    	if (n < 2 || i*i <= n)
    		return 0;
    	return 1;
    }
    
    int main()
    {
    	int i;
    	for (i = -50; i < 50; i++)
    		if (isPrime(i))
    			printf("%d\n", i);
    	return 0;
    }
    
    展开全文
  • 如题 for (i = 1; i*i<= n; i++) f 这个时间复杂度是n还是根号n? 这个时间复杂度是n还是根号n
  • 但是我们要得到根号n的时间复杂度,所以我们要进行改善,经过仔细的思考观察,发现有以下几个改善的途径。 (1)没有必要检查所有的因子,只要发现任何一个大于1小于n的因子,就能停下来报告n不是

    判断一个数是不是素数最简单直接的方法就是从素数的定义出发。检查1~n之间的所有数,从中找出n这个数的所有因子,检查因子个数是否为两个。如果正好是两个因子,则为素数,否则为非素数。这样该算法的时间复杂度是O(n)。

    但是我们要得到根号n的时间复杂度,所以我们要进行改善,经过仔细的思考观察,发现有以下几个改善的途径。
    (1)没有必要检查所有的因子,只要发现任何一个大于1小于n的因子,就能停下来报告n不是素数。
    (2)一旦函数已经检查了n是否能被2整除,就不需要检查是否能被其他偶数整除。如果n能被2整除,程序就停下来,报告n不是素数。如果n不能被2整除,那么它也不可能被4或6或其他偶数整除。因此,isPrime只需要检查2和奇数。但注意有个特例,2能被2整除,但2是素数。
    (3)该问题不需要检查到n为止。实质上,它可以在一半的地方就停止,因为任何大于n/2的值不可能被n整除。然而再进一步思考一下,还可以证明,该程序不需要试探任何大于n的平方根的因子。当n能被某一个整数d1整除时,那么就肯定还有另一个数d2能被它整除,即n=d1*d2,如果其中一个大于n的平方根,另一个一定小于n的平方根。因此如果n有任何因子,肯定有一个小于或等于n的平方根。这就意味着程序中的for循环的次数i<=根号n

    #include <iostream>
    #include <math.h>
    
    
    bool isPrime(int n){
        if(n<=1) return false;
        if(n==2) return true;
        if(n%2==0) return false;
        int limit=sqrt(n)+1;
        for(int i=3;i<=limit;i+=2)
            if(n%i==0) return false;
        return true;
    }
    
    int main() {
        // insert code here...
        int a;
        scanf("%d",&a);//输入测试的数
        if(!isPrime(a)) printf("不是素数");
            else printf("是素数");
        return 0;
    }
    展开全文
  • 查询时:点x的周围节点,度数小于等于根号n的节点更新对x造成的影响已经更新。只需要考虑度数大于根号n的节点更新对x造成的影响。由于x周围度数大于根号n节点不会超过根号n个,所以此次更新影响也是根号n级别

    更新一下这题的n*sqet(n)解法。

    我们发现:这题要么更新是O(n),查询是O(1),要么更新是O(1),查询是O(n).

    我们可以采取均摊复杂度的思想,让查询和更新都做到O(sqrt(n)).

    每次更新:若当前节点的度数小于等于根号n,那么则暴力更新其周围节点。否则不管,其影响留到查询时更新。

    查询时:点x的周围节点,度数小于等于根号n的节点更新对x造成的影响已经更新。只需要考虑度数大于根号n的节点更新对x造成的影响。由于x周围度数大于根号n节点不会超过根号n个,所以此次更新影响也是根号n级别的。等查询完mex后,消除影响。

    这样可以不用维护影响的变化。然后这样更新和查询都是根号n次。

    我们用分块维护mex。把vs数组进行分块,显然mex表示从前往后,第一个不满的块中第一个vs为0的数。

    所以我们只需要维护每个块是否为满即可。所以每次更新只需要让点val所在块的度数加减1即可,这里是O1更新的。

    而最后查询时根号n即可。注意这里的查询根号n与更新根号n是独立的,即复杂度分开。

    所以总复杂度为:O(n*sqrt(n)) !;

    注意:vector重新定义空间最好用assign(n,a),开辟n个元素,并且都赋值为a,而resize赋值不会赋值已经存在的元素。因为这卡半天。。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define ls (o<<1)
    #define rs (o<<1|1)
    #define pb push_back
    const int M = 1e5+7;
    vector<int>v[M],g[M];
    struct Block {
      	vector<int>nm,vs,bel;
    	vector<pair<int,int> >rg;
    	int bs,sz,V;
    	void build(int u)
    	{
    		V=g[u].size()+1;sz=sqrt(V+0.5);
    		rg.clear();bs=0;vs.clear();
    		nm.assign(V+1,0);bel.assign(V+1,0);
    		for(int i=0;i<=V;i+=sz)
    		{
    			rg.emplace_back(i,min(i+sz-1,V));
    			for(int j=i;j<=min(i+sz-1,V);j++)bel[j]=bs;
    			++bs;
    			vs.pb(0);
    		}
    	}
    
    
    	void ins(int x)
    	{
    		if(x>V)return ;//mex不可能比V还大(因为最多V个数,mex最大为 V+1,有用数的最大为 V) 
    		nm[x]++;
    		if(nm[x]==1)vs[bel[x]]++;
    	}
    	void del(int x)
    	{
    		if(x>V)return ;
    		nm[x]--;
    		if(nm[x]==0)vs[bel[x]]--;
    	}
      	int qu()
    	{
    		for(int i=0;i<bs;i++)
    		{
    			if(vs[i]==rg[i].second-rg[i].first+1)continue;//这一块满了,最小不存在整数不在这一块
    			for(int j=rg[i].first;j<=rg[i].second;j++)
    				if(!nm[j])return j;
    		} 
    		return V+1;
    	}
    } p[M];
    
    //struct BLOCK{
    
    
    //}p[M];
    int a[M];
    int main()
    {
    
      	int T;
    	cin>>T;
    	while(T--)
    	{
    		int n,m;
    		scanf("%d%d",&n,&m);
    		int SZ=sqrt(n+0.5);
    		for(int i=1;i<=n;i++)scanf("%d",&a[i]),g[i].clear(),v[i].clear();
    		for(int i=1;i<=m;i++)
    		{
    			int x,y;
    			scanf("%d%d",&x,&y);
    			g[x].pb(y),g[y].pb(x);
    		}
    		for(int x=1;x<=n;x++)
    		{
    			p[x].build(x);
    		//	cout<<"ojk1"<<endl;
    			for(auto y:g[x])
    			{
    				if(g[y].size()>SZ)v[x].pb(y);
    				else p[x].ins(a[y]);
    			}
    		}
    		int q;
    		scanf("%d",&q);
    		while(q--)
    		{
    			int ty,x,y;
    			scanf("%d",&ty);
    			if(ty==1)
    			{
    				scanf("%d%d",&x,&y);
    				if(g[x].size()<=SZ)
    				{
    					for(auto t:g[x])
    					{
    						p[t].del(a[x]);
    						p[t].ins(y);
    					}
    				}
    				a[x]=y;
    			}
    			else
    			{
    				scanf("%d",&x);
    				for(auto t:v[x])
    					p[x].ins(a[t]);//点x周围,size>SZ的点还未更新周围
    				printf("%d\n",p[x].qu());
    				for(auto t:v[x])
    					p[x].del(a[t]);
    			}
    		}
    	} 
    	return 0;
    }

     

    展开全文
  • 可以发现其实不用一个个去检验哪个同余x,因为是从1开始到n找出所有同余x正整数,由题意x一定小于等于p,所以所有和x模p同余整数就是x+k*p 从另一个角度来说,做题时候一定要从原本描述中抽象出核心含义,这...

    我一开始打了个暴力,直接n^2枚举。。。看哪个同余x,但是有个办法能更快一点,复杂度取决于模数p。可以发现其实不用一个个去检验哪个同余x,因为是从1开始到n找出所有同余x的正整数,由题意x一定小于等于p,所以所有和x模p同余的整数就是x+k*p
    从另一个角度来说,做题的时候一定要从原本描述中抽象出核心含义,这道题问x池内的综合,就是问所有模p同余的下标对应的数之和(抽象出题意有助于帮助我们想起以前的知识,找到思路)
    但是当p很小的时候复杂度仍然是n^2的,考虑到n的数量级是100000的,n*sqrt(n)的复杂度是可以过的。
    先预处理出根号p以内的一些东西:设ans[p][k]表示在模p时(1 <= p < sqrt(n)),k池子(即所有%p同余的下标对应数的和)的答案,那么思考每个数的贡献(转换为算贡献是个很常用的做法,一般让统计满足要求的数我们可以反过来求每个数的贡献)
    然后大于sqrt(n)的直接暴力统计,复杂度n*sqrt(n)
    就是考虑每一个a[i]能为什么做贡献,于是有:

    for(int i=1; i<=n; i++) {
        for(int j=1; j<=siz; j++) {
            ans[j][i%j] += a[i];//考虑每一个ai为哪个答案贡献
        }
    }
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int MAXN = 150000 + 10;
    int n,m,q,a[MAXN],ans[MAXN][400];
    int main() {
        scanf("%d %d", &n, &m);
        for(int i=1; i<=n; i++) {
            scanf("%d", &a[i]);
        }
        int siz = sqrt(n);
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=siz; j++) {
                ans[j][i%j] += a[i];//考虑每一个
            }
        }
        for(int i=1; i<=m; i++) {
            char cmd;
            cin >> cmd;//这里若用scanf貌似要处理换行符,防止错误就用cin吧
            int x,y;
            scanf("%d %d", &x, &y);
            if(cmd == 'A') {
                if(x > siz) {
                    int sum = 0;
                    for(int i=y; i<=n; i+=x) 
                        sum += a[i];
                    printf("%d\n", sum);
                } else {
                    printf("%d\n", ans[x][y]);
                }
            } else {
                for(int p=1; p<=siz; p++)
                    ans[p][x%p] = ans[p][x%p] - a[x] + y;
                a[x] = y;         
            }
        }
        return 0;
    }
    展开全文
  • PS:新手上路,实在找不到怎么转载,所以只能模仿某平台在名字前加转载两个字了。虽然征得原文博主同意对这篇文章进行转载,但是,由于找不...如果原文博主觉得这样不合适话,您言语一声,我把这篇文章删掉哈~ ...
  • 根号n段归并排序算法

    2020-10-26 22:55:49
    根号n段归并排序算法C++代码实现: 1.合并【根号n向下取整】段子数组,使用了自底向上两两合并策略。 2.算法总体时间复杂度为nlogn 3.带有详细注释
  • LightOJ - 1245 根号n暴力

    2018-01-15 17:24:00
    根号n时每个i贡献值相差很小,可以利用公式优化(函数C) 但是注意不能一整段使用公式,否则复杂度还是会劣化到O(n)(显然对gongxian只能逐步递减) 网上看了不少代码,但是都没有对贡献值边界问题给定明确判断 ...
  • n\sqrt {n}n​时间复杂度 ll f(ll x){ ll num = 0; for(ll i=1;i*i<=x;i++){ if(x%i==0) num+=2; if(i*i==x) num--; } return num; }
  • 在判断n是否为素数时,为什么是循环到根号n就可以退出循环? 如果要判断n是否为素数,就需证明n除了1和它本身之外,没有其他因数。 这个问题可以从另外一个方面考虑,假设n存在一个最小因数p(!=1 and !=n),则...
  • 今天纠结了整整一下午的这个题,当心不静的时候,世界就更加浮躁。也许不应该这样,但是如果能时刻控制自己,那现在的我应该在家里等待笔试而...当然对于N的平方的解法可以做一些优化,其实我们第二次只需要遍历到根号N
  • 求欧拉函数几种方法

    千次阅读 2017-08-17 11:06:39
    2 O根号n的复杂度: phi()函数 3 筛法先求素数 O(x): x为根号n内的素数 prime_phi()函数includeincludeincludeusing namespace std; typedef long long ll; const int maxn=5e4; bool isprime
  • 利用指数循环节,枚举i,达到根号n的复杂度 ll qpow(int a,int b,int p) { ll ans=1; while(b) { if(b&1)ans=ans*a%p; a=a*a%p; b/=2; } return ans; } int bsgs(int a,int b,int p)// a^x \equiv ...
  • XTU 1203 A simple problem

    2016-03-03 09:54:27
    http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1203首先倒着看,这题目肯定是根号n的复杂度,那么后根号n的数量比较分散,发现等差数列后即可求和去算, 前根号n的数正常算就ok!然后发现需要高...
  • 已知两个有序序列a(1)---a(m)和a(m+1)----a(n),并且其中一个序列记录个数小于根号n,用O(n)时间和O(1)空间完成他们归并。
  • 一、单选题 解析:从要满足条件下手,或者终止条件下手,因为这里...根号x-1时候停止,因为y每一次加1,所以基本语句频度为根号x-1,所以时间复杂度根号x; 对于选择语句,看最坏情况,时间
  • 第一次用分块,感觉超方便啊; 如果记录每个点的弹力系数,那么是O(1)修改O(n)查询;...那么如果分成根号n块,则相当于每块都路径压缩,修改和查询都是根号n的复杂度! 代码如下: #include&l...
  • 水水的数学题 枚举gcd所以 ans=∑d*∑gcd(i,n)==d=∑d*∑gcd(i/d,n/d)==1 第二个求个可以显然发现就是欧拉函数,问题解决 ...只用每一次根号n的复杂度暴力求就好了脑残。 #include #include #include #inc
  • CCF CSP 2020-06-04 1246

    千次阅读 热门讨论 2021-01-21 17:08:50
    根据最大的测试数据 n可取到1e9 可知 应该采取logn或者 根号n的 复杂度的算法 目测是一个动态规划 然后利用矩阵乘法来加速运算,根据输入的字符串推出他是由1246中的哪一个转移形成的 然后输出即可 #include <...
  • 由题意知当i小于等于n的时候进行循环,运算的时间复杂度得出应该为n,因此O(n) 第二题 由题意知可以看出这是两个嵌套的循环,且每一个嵌套的时间复杂度均为n,则总体的时间复杂度应该为O(n2) 第三题 由题意知...
  • Miller Rabin

    2016-10-02 15:07:11
    正常的素数判定,要么是直接枚举因子,通过根号n的复杂度来完成,这样时间可能不够,又或是先通过打表之后,去查表,可是这样空间复杂度过大.所以说,对于小于1e18的数,这些方法是毫无作用的.那么怎么来判断小于1e18的数...
  • 这道题利用根号分治可以把复杂度降到n根号n级别。 我们发现当物品体积大与根号n时,就是一个完全背包,换句话说就是没有了个数限制。 进一步我们发现,这个背包最多只能放根号n个物品。 所以我们设dp[i][j]表示放...
  • 传送门: ...!!!由打表找规律得f(x)=x+1 ...要注意一下欧拉函数的写法,刚开始还是想错了,确实是根号n的复杂度就可以了,把n质因数分解了,写成那个质因数的表达形式,然后遇到一个质因数,一
  • 计算不等式x>=(y-1)*(y-1),得出y<=(根号x)+1,忽略常数得出时间复杂度O(根号x),常数项忽略,低次项忽略 转载于:https://www.cnblogs.com/sddzlsc/p/5678195.html
  • C: 题目:80/100,大数据部分没有通过,也不知是不是数据产生溢出问题;...=n/根号2,减少穷竭搜索; #include<iostream> #include<cstring> #include<cstdio> #include<algo...
  • CODEVS3550 不一样的根号算法

    千次阅读 2015-03-28 16:51:54
    比较常见,而O(sqrt(n))的复杂度并不常见,只有分块、朝鲜树(似乎并不常用但确实复杂度带根号)但是在某些意想不到的地方,可以使用根号算法,不仅效果不错,还比较好写。 引出我们今天的题目CODEVS 3550,已知...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 309
精华内容 123
关键字:

根号n的复杂度