• 【题解】[Codeforces 1305F] Kuroni and the Punishment | 20210920 模拟赛 最大公约数(gcd)【随机化 抽屉原理】


    题目链接

    题目链接

    题意

    给定 (n) 个正整数,一次操作可以将其中一个加减一,求最少操作数使得所有数都是正整数且 gcd 大于 1。(nleq 2 imes 10^5,a_ileq 10^{12})

    题解

    注意到答案不超过 (n)(gcd=2),考虑如果 gcd 不是小质数(的倍数),那么需要加减 2 的数不超过一半。我们多次随机两个数,求其(加减一/不变)后的 gcd,并钦定 gcd 为其约数,计算代价。每次随机有不少于 (dfrac{1}{2}) 的概率正确。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll getint(){ ll x;scanf("%lld",&x);return x; }
    const int N=2e5+10,K=300,T=1e4;
    mt19937 rnd;
    int pri[K],cnt; bool boo[K+10];
    
    int n;
    ll a[N];
    map<ll,int>mp;
    ll gcd(ll x,ll y){
    	return x?gcd(y%x,x):y;
    }
    pair<ll,int>q[N];
    int main(){
    	freopen("gcd.in","r",stdin);
    	n=getint();
    	for(int i=1;i<=n;i++)a[i]=getint();
    	
    	for(int i=2;i<=K;i++){
    		if(!boo[i])pri[cnt++]=i;
    		for(int j=0;j<cnt&&i*pri[j]<=K;j++){
    			boo[i*pri[j]]=0;
    			if(i%pri[j]==0)break;
    		}
    	}
    	
    	ll ans=n;
    	for(int i=0;i<cnt;i++){
    		int p=pri[i];
    		ll v=0;
    		for(int j=1;j<=n;j++){
    			if(a[j]<p)v+=p-a[j];
    			else{
    				ll t=a[j]%p;
    				v+=min(t,p-t);
    			}
    		}
    		ans=min(ans,v);
    	}
    	
    	for(int _=0;_<10;_++){
    		int x=rnd()%n+1,y=rnd()%n+1;
    		for(int d:{-2,-1,0,1,2}){
    		    if(min(a[x],a[y])+d<=0)continue;
    			ll g=gcd(a[x]+d,a[y]+d);
    			for(int j=0;j<cnt;j++)while(g%pri[j]==0)g/=pri[j];
    			mp[g]++;
    			
    			for(int p=2;p*1ll*p<=g;p++){
    				if(g%p==0){
    					ll v=0;
    					for(int j=1;j<=n;j++){
    						if(a[j]<p)v+=p-a[j];
    						else{
    							ll t=a[j]%p;
    							v+=min(t,p-t);
    						}
    					}
    					ans=min(ans,v);
    				}
    				while(g%p==0)g/=p;
    			}
    			if(g!=1){
    				ll p=g;
    				ll v=0;
    				for(int j=1;j<=n;j++){
    					if(a[j]<p)v+=p-a[j];
    					else{
    						ll t=a[j]%p;
    						v+=min(t,p-t);
    					}
    				}
    				ans=min(ans,v);
    			}
    		}
    	}
    	cout<<ans;
    }
    
    

    花絮:搬题人的数据非常水,输出 (n-1) 就能过题。

    知识共享许可协议
    若文章内无特别说明,公开文章采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
  • 相关阅读:
    Flutter-常用插件庫
    Flutter-發送短信驗證碼
    Flutter-Radio單選框
    Flater-Provide狀態管理
    android sdk安装
    Android Studio的安装
    Flutter SDK安装(windows)
    Flutter-dialog彈出框
    python中的迭代器与生成器
    python闭包与装饰器
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/15357994.html
Copyright © 2020-2023  润新知