Link
题意:
思路:
Jiangly都没做出来的题,原来这么操蛋,首先我们要发现一个性质,我们最多操作n次可以使得gcd>1,把ai变成偶数,所有ans<=n,然后可以有个更牛逼的性质,被操作两次及以上的数,不超过
⌊
n
/
2
⌋
\lfloor n/2 \rfloor
⌊n/2⌋个,也就是说我们有大于
⌊
n
/
2
⌋
\lfloor n/2 \rfloor
⌊n/2⌋个数仅仅只操作一次或者不操作,那么也就是会有大于1/2的概率gcd的质因子会出现在里面,然后只要我们多选几个数,这个概率就会惊人的高,假设选了k个数,也就是我们的概率能达到
1
−
1
2
k
1-\frac{1}{2^k}
1−2k1随机化一下,每次任意选k个数,然后
s
q
r
t
(
n
)
sqrt(n)
sqrt(n)暴力分解质因数就行了。
AC代码:
//#pragma GCC target("avx")
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int,int> pii;
const int N = 400010;
const int mod=998244353;
inline int read()
{
int res=0;
int f=1;
char c=getchar();
while(c>'9' ||c<'0')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
res=(res<<3)+(res<<1)+c-'0';
c=getchar();
}
return res;
}
bool st[1010];
int d[1010];
int stt[1010];
vector<int>v[N];
int lca(int x,int y){
cout<<"?"<<" "<<x<<" "<<y<<endl;
cout.flush();
int root;
cin>>root;
return root;
}
#define int long long
int a[200010];
mt19937 rd(time(NULL));
signed main()
{
int n;
cin>>n;
// srand(time(NULL));
for(int i=1;i<=n;i++) cin>>a[i];
shuffle(a+1,a+1+n,rd);
vector<int>v;
for(int i=1;i<=min(70ll,n);i++){
// int pos=
// while(){
// }
int x=a[i];
for(int j=2;j*j<=x;j++){
if(x%j==0){
v.push_back(j);
while(x%j==0) x/=j;
}
}
if(x>1)
v.push_back(x);
x=a[i]-1;
for(int j=2;j*j<=x;j++){
if(x%j==0){
v.push_back(j);
while(x%j==0) x/=j;
}
}
if(x>1)
v.push_back(x);
x=a[i]+1;
for(int j=2;j*j<=x;j++){
if(x%j==0){
v.push_back(j);
while(x%j==0) x/=j;
}
}
if(x>1)
v.push_back(x);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
int res=1e18;
for(auto j:v){
// cout<<j<<endl;
int cnt=0;
for(int i=1;i<=n;i++)
{
if(a[i]<j){
cnt+=j-a[i];
continue;
}
cnt+=min(a[i]%j,j-a[i]%j);
}
// cout<<j<<" "<<cnt<<endl;
res=min(res,cnt);
}
cout<<res;
return 0;
}
/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/