题解:CF1731E Graph Cost
Kotobuki_Tsumugi · · 题解
首先有一个结论,能选大的
证明:我们要使花费代价最小,然而添加的边数是固定的,即,我们要让添加的平均代价最小。那么如果选
那么我们就从
最大公约数有一个性质:若
那么我们判断最大公约数就可以转化为:从
也就是要解决这样一个问题:求
怎么解决?暴力枚举+根号枚举判断?太慢了,是
有互质,可以往欧拉函数上面想。根据欧拉函数的定义,有
这个定义很优美。为什么这么说?可以想到,其前缀和
求
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6+10;
int phi[N],sum[N],Prime[N],cnt;
bool vis[N];
void Getphi(){
phi[1] = 1;
for(int i = 2;i<N;i++){
if(!vis[i]){
vis[i] = i;
Prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1;j<=cnt;j++){
if(i*Prime[j] > N) break;
vis[i*Prime[j]] = Prime[j];
if(i%Prime[j] == 0){
phi[i*Prime[j]] = phi[i]*Prime[j];
break;
}
phi[i*Prime[j]] = phi[i]*phi[Prime[j]];
}
sum[i] = sum[i-1] + phi[i];
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T;
Getphi();
while(T--){
int n,m,ans = 0;
cin>>n>>m;
for(int k = n;k>=1;k--){
int maxn = min(sum[n/(k+1)],m)/k;
ans += maxn * (k+1);
m -= maxn * k;
}
cout<<(m > 0 ? -1 : ans)<<'\n';
}
return 0;
}