[2019CCPC网络选拔赛] huntian oy (杜教筛)

hdu跳转

可以打个暴力找找规律
发现答案就是 ∑ i = 1 n ∑ j = 1 i ( i − j ) [ g c d ( i , j ) = = 1 ] \sum_{i=1}^n\sum_{j=1}^i(i-j)[gcd(i,j)==1] i=1nj=1i(ij)[gcd(i,j)==1]
对于同一个i,i-j和j是对称的,上下和为i,且有 ϕ ( i ) \phi(i) ϕ(i)个。
它等同于求 ∑ i = 1 n ϕ ( i ) ∗ i ∗ 0.5 \sum_{i=1}^n{\phi(i)*i*0.5} i=1nϕ(i)i0.5
这是一个经典问题,可以看这

#include 
#include 
#include 
#include 
#include 
//#include 

using namespace std;

const int MAXX=3000000;

typedef long long LL;
const LL Mod = 1000000007;
LL v[MAXX],phi[MAXX],p[MAXX];
       
void init() {
    v[1] = phi[1] = 1;
    int cnt = 0;
    for (int i = 2; i < MAXX; i++) {
        if (!v[i]) {
            p[++cnt] = i;
         //   mu[i] = -1;
            phi[i] = i-1;
        }
        for (int j = 1; j <= cnt && p[j]*i < MAXX; j++) {
            v[i*p[j]] = 1;
            if (i%p[j]) {
          //      mu[i*p[j]] = -mu[i];
                phi[i*p[j]] = phi[i]*phi[p[j]];
            } else {
           //     mu[i*p[j]] = 0;
                phi[i*p[j]] = phi[i]*p[j];
                break;    
            }
        }
    }
    for (int i = 1; i < MAXX; i++) {
        //mu[i] += mu[i-1];
        phi[i] = (phi[i-1]+phi[i]*i%Mod)%Mod;
    }
 }       

LL qpow(LL a,LL b) {
    LL ans = 1;
    for ( ; b; b>>=1,a = (a*a)%Mod) 
      if (b&1) ans = (ans*a)%Mod;
    return ans;
}

LL inv2 = qpow(2,Mod-2),inv6 = qpow(6,Mod-2);

map<int,LL> pp;

LL sumiPhi(int x) {
    if (x < MAXX) return phi[x];
    if (pp[x]) return pp[x];
    LL mod = Mod,n = x;
    LL ans = 1LL*n*(n+1LL)%Mod*(2LL*n%Mod+1)%Mod*inv6%Mod;
    for (int i = 2,j; i <= n; i = j+1) {
        j = n/(n/i);
        LL tp = 1LL*(j-i+1LL)*(j+i)/2; tp%=Mod;
        ans = ((ans-1LL*tp%Mod*sumiPhi(n/i)%Mod)%Mod+Mod)%Mod;
    }
    return pp[x] = ans;
}
   
int main() {
    LL T,n,a,b;
    cin >> T;
    init();
    while(T--) {
        scanf("%lld%lld%lld",&n,&a,&b);
        if(n==1) cout << "0\n";
        else printf("%lld\n",(sumiPhi(n)-1LL+Mod)%Mod*inv2%Mod);
    } 
    return 0;
}

Problem Description
One day, Master oy created a new function to celebrate his becoming a ‘huntian’ in majsoul.
f(n,a,b)=∑ni=1∑ij=1gcd(ia−ja,ib−jb)[gcd(i,j)=1]%(109+7)
Given n, a and b, Master oy wanted Newbie jj who was still a ‘chuxin’ to answer the value of f(n,a,b).
Input
There are multiple test cases.
The first line contains an integer T, indicating the number of test cases.
For each test case, there are three positive integers n, a and b which are separated by spaces. It’s guaranteed that a and b are coprime.
1≤n,a,b≤109
T=104, but there are only 10 test cases that n is over 106.
Output
For each test case, an integer in one line representing your answer.

你可能感兴趣的:(OI/ACM,Solution,莫比乌斯反演,杜教筛)