1. 程式人生 > >[luogu1447][bzoj2005]能量采集

[luogu1447][bzoj2005]能量采集

efi += long min 需要 能量采集 fin long long sca

先扔結論:點(a,b)與(0,0)之間有的數量為gcd(a,b)-1(怎麽證的??留給出題人)

我們求ans為所有gcd之和,但是復雜度過大,達到了O(n*m),會T

於是想到一個容斥的辦法:設F[i]表示因數中有i的數對組數,然後通過容斥地減去i的所有倍數的F,來得出原本的答案

需要註意的是要開longlong

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll F[100010],ans;
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    
for(int i=1;i<=min(n,m);i++) F[i]=(ll)(n/i)*(m/i); for(int i=min(n,m);i>=1;i--) for(int j=i*2;j<=min(n,m);j+=i) F[i]-=F[j]; for(int i=1;i<=min(n,m);i++)ans+=(ll)F[i]*i; printf("%lld",ans*2-(ll)n*m); return 0; }

[luogu1447][bzoj2005]能量采集