luogu_P1447 [NOI2010]能量采集

传送门:https://www.luogu.org/problem/P1447

答案为  Σ1~nΣ1~m(gcd(i,j)*2-1)  =  Σ1~nΣ1~m(gcd(i,j)*2)-n*m

考虑  gcd(i,j)的取值为x    记录cnt[x]=n/x * m/x   出现公因数x的对数

g[x]为最大公因数为x的对数      g[x]=cnt[x]-(cnt[2*x]+cnt[3*x]......)

最后答案为ans=(Σx*g[x]*2)-n*m;

注意longlong

#include<cstdio>
#include<algorithm>
#define  R register
typedef long long ll;
using namespace std;
int n,m;
ll cnt[100100],g[100100],ans;
int main (){
    scanf("%d%d",&n,&m);
    for(R int i=1;i<=max(n,m);i++){
        cnt[i]=1ll*(n/i)*(m/i);
    }
    for(R int i=max(n,m);i;i--){
        g[i]=cnt[i];
        int x=i*2;
        while(x<=max(n,m)){
            g[i]-=g[x];
            x+=i;
        }
    }
    for(R int i=1;i<=max(n,m);i++) ans+=1ll*i*g[i];
    printf("%lld",ans*2ll-1ll*n*m);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/coclhy/p/11773217.html