# bzoj2005 [Noi2010]能量采集

ans=ni=1mj=12gcd(i,j)1=2ni=1mj=1gcd(i,j)nm$ans=\sum_{i=1}^{n}\sum_{j=1}^{m}{2gcd(i,j)-1}=2\sum_{i=1}^{n}\sum_{j=1}^{m}gcd(i,j) -nm$
1ϕ=u$1*\phi=u$来化

ans=2i=1nj=1md|i,d|jϕ(d)nm

ans=2d=1d=min(n,m)nd×md×ϕ(d)nm

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
#define N 100100

LL cnt,pri[N/4],phi[N];bool ispri[N];
LL mymin(LL x,LL y){return (x<y)?x:y;}
void Eular(LL lim)
{
cnt=0;phi[1]=1;
for (LL i=2;i<=lim;i++)
{
if (!ispri[i]) {pri[++cnt]=i;phi[i]=i-1;}
for (LL j=1;j<=cnt && pri[j]*i<=lim;j++)
{
LL k=i*pri[j];
ispri[k]=true;
if (i%pri[j]==0)
{
phi[k]=pri[j]*phi[i];
break;
}
phi[k]=(pri[j]-1)*phi[i];
}
}
for (LL i=2;i<=lim;i++) phi[i]+=phi[i-1];
}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
LL n,m,i,lim,r,ans=0;
scanf("%lld%lld",&n,&m);
lim=mymin(n,m);Eular(lim);
for (i=1;i<=lim;i=r+1)
{
r=mymin(n/(n/i),m/(m/i));
ans+=(n/i)*(m/i)*(phi[r]-phi[i-1]);
}
ans=2*ans-(n*m);
printf("%lld\n",ans);
return 0;
}

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客