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;
}