Gcd小练习2(LuoGu)

P1414 又是毕业季II

预处理每个因数出现的次数,因为随 i i i增加,答案是非递增的。

所以维护一个 m x mx mx即可。

int mx=0;scanf("%d",&n);for(int i=1;i<=n;i++){
		int x;scanf("%d",&x);mx=max(x,mx);
		for(int i=1;i*i<=x;i++)
			if(x%i==0){
				a[i]++;
				if(i*i!=x) a[x/i]++;
			}
	}
	for(int i=1;i<=n;i++){
		while(a[mx]<i) mx--;
		printf("%d\n",mx);
	}
P5535 【XR-3】小道消息

数论问题,最后一种情况还没弄懂。

k = k + 1 , n = n + 1 k=k+1,n=n+1 k=k+1,n=n+1

  • k k k是质数。

    • 2 k > n 2k>n 2k>n,即不存在它的倍数,显然1步即可。
    • 否则2步,第2天 ( k , k + 1 ) , ( 2 k , 2 ( k + 1 ) ) (k,k+1),(2k,2(k+1)) (k,k+1),(2k,2(k+1))传消息即可。
  • k k k不是质数。

    也只需要2步,根据伯特兰-切比雪夫定理可知必定存在一个质数 p ∈ ( n 2 . n ) p\in(\dfrac{n}{2}.n) p(2n.n)满足条件,第1步传给它,然后第2步它传给其他的数。

bool ck(ll n){
	for(ll i=2;i*i<=n;i++)
		if(n%i==0) return false;
	return true;
}
ll n,k;cin>>n>>k;
	k++,n++;
	if(ck(k)&&2*k>n) cout<<1<<'\n';
	else cout<<2<<'\n';

Miller Rabin (MR)判素数

时间复杂度 O ( k l o g 3 n ) O(klog^3n) O(klog3n)

int d[8]={2,3,5,7,11,13,79,97};
ll qmul(ll a,ll b,ll m){
	return (ll)(__int128(a)*b%m);
}
ll ksm(ll a,ll n,ll m=mod){
	ll ans=1;
	while(n){
		if(n&1) ans=qmul(ans,a,m);
		a=qmul(a,a,m);
		n>>=1;
	}
	return ans;
}
bool ck(ll n){
	if(n<3) return n==2;
	if(n%2==0) return 0;
	ll p=n-1,c=0;while(p%2==0) p>>=1,c++;
	for(int i=0;i<8;i++){
		if(d[i]==n) return 1;
		ll x=ksm(d[i],p,n),y=x;
		for(int j=0;j<c;j++){
			x=qmul(x,x,n);
			if(x==1&&!(y==1||y==n-1)) return 0;
			y=x;
		}
		if(x!=1) return 0;
	}return 1;
}
int main(){
	ll n,k;scanf("%lld%lld",&n,&k);
	k++,n++;
	if(ck(k)&&2*k>n) puts("1");
	else puts("2");
	return 0;
}