int nums[N]; voidget_primes(int n){ bool vis[N]; int cnt=0; for (int i=2;i<=n;i++){ if (!vis[i]){ nums[cnt++]=i; } for (int j=0;nums[j]*i<=n;j++){ vis[nums[j]*i]=true; if (i%nums[j]==0){ break; } } } //nums; }
196. 质数距离
196. 质数距离
求出在【L,R】区间内某两个质数分别是距离最小的和距离最大的。
性质一 : 数字N如果是一个合数,则N一定存在一个小于等于sqrt(N)的质因子。
假设a和b是N的两个质因子,则ab=N,假设 a<=b,则 a a <= a * b = N,则可以得出:a<=sqrt(N)
性质二: 如果x属于【L,R】的区间中合数,则一定存在一个p值,满足p<=sqrt(N),并且这个p值 是x的一个质因子,则便可以通过 p 值来筛选出在【L,R】区间中的每一个合数。
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<limits.h> usingnamespace std; constint N = 1e6+10; #define int long long int l,r; int nums[N],cnt; bool temps[N]; //线氏筛求质数: O(N) voidget_num(int n){ memset(temps,0,sizeof(temps)); for (int i=2;i<=n;i++){ if (!temps[i]){ nums[cnt++]=i; } for (int j=0;nums[j]*i<=n;j++){ temps[nums[j]*i]=true; if (i%nums[j]==0){ break; } } } } signedmain() { //预处理质数 while (cin>>l>>r){ get_num(50000); /* 如果N是一个合数,则N一定存在一个小于等于sqrt(N)的质数: 假设a和b是N的两个质数,并且假设a<=b,则 a*a <= a*b = N, 则 a<=sqrt(N),a就是N的一个小于等于sqrt(N)的质数 */ //1. 首先筛出[1,50000]之间所有的素数 //2. 把 [L,R]范围内的所有的合数“删除”掉,则剩下的就是目标范围内的质数 memset(temps,0,sizeof(temps)); for (int i=0;i<cnt;i++){ int p=nums[i];//取得每一个[1,50000]之间的质数,对这个数字取倍数,则生成的数字一定是合数 for (int j=max((l-1)/p+1)*p,2*p);j<=r;j+=p){ temps[j-l]=true; //相当于离散化,防止数组下标过大,减去左边界 } } cnt=0; for (int i=0;i<=r-l;i++){ if (!temps[i] && i+l>1){ nums[cnt++]=i+l;//再加上l,就变成了原数 } } if (cnt<2){ cout<<"There are no adjacent primes.\n"; } else{ //获得答案 int minp=0,maxp=0; for (int i = 0; i+1 < cnt; i ++ ){ int d=nums[i+1]-nums[i]; if (d<nums[minp+1]-nums[minp]){ minp=i; } if (d>nums[maxp+1]-nums[maxp]){ maxp=i; } } printf("%d,%d are closest, %d,%d are most distant.\n",nums[minp],nums[minp+1],nums[maxp],nums[maxp+1]); } } return0; }
求组合数
求组合数:C(n,k),即在 n个数字中选择k个数字。
1 2 3 4 5 6 7 8 9
int C[N][N]; voidget(){ for (int i=0;i<=n;i++){ for (int j=0;j<=i && j<=k;j++){ //小于等于k为一个小优化 if (!j) C[i][j]=1; //j为零的时候初始化,即C(i,0)=1 else C[i][j]=C[i-1][j-1]+C[i-1][j]; //类似于杨辉三角 } } }
通过这种方式得到C(n,k)的值:C[n][k]
时间复杂度:O(N^2)
快速幂
计算X ^ N % mod的值
模板代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
#define int long long int x,n,mod=9999999; intget(){ int ans=1;//初始化为1 for (;n;n>>=1){ if (n&1){ ans=ans*x%mod; } x=x*x%mod; } return ans; }