BZOJ 2693: jzptab Mobius multiplicative function inversion + + sieve

Code:

#include<bits/stdc++.h>
#define ll long long 
#define M 10001000
#define maxn 10200100 
#define MOD 100000009
using namespace std;
int cnt, tot;   
int vis[maxn],mu[maxn], prime[maxn]; 
ll h[maxn], sumv[maxn];  
void init()
{
    int i,j; 
    h[1]=1; 
    for(i=2;i<M;++i) 
    {
        if(!vis[i]) prime[++tot]=i, h[i]=(i-(ll)i*i)%MOD; 
        for(j=1;j<=tot&&prime[j]*i<M;++j) 
        {
            vis[prime[j]*i]=1; 
            if(i%prime[j]==0) 
            {
                h[prime[j]*i]=(prime[j]*h[i])%MOD; 
                break; 
            }
            else  h[prime[j]*i]=(h[prime[j]]*h[i])%MOD; 
        }
    }
    for(i=1;i<M;++i)   sumv[i]=(sumv[i-1]+h[i])%MOD; 
}
ll SUM(ll x,ll y)
{
    x%=MOD, y%=MOD; 
    ll r1=(x*(x+1)>>1)%MOD; 
    ll r2=(y*(y+1)>>1)%MOD;
    return (r1*r2)%MOD;  
}
ll query(ll n,ll m)
{
    int i,last,re=0,j; 
    if(n>m) swap(n,m); 
    for(i=1;i<=n;i=j+1)
    {
        j=min(n/(n/i), m/(m/i)); 
        re += SUM(n/i, m/i) * (sumv[j]-sumv[i-1])%MOD; 
        re%=MOD; 
    }
    return (re+MOD)%MOD; 
}
int main()
{
    init(); 
    int n,m,T; 
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m); 
        printf("%lld\n",query(n,m)); 
    }
    return 0; 
}

  



Guess you like

Origin www.cnblogs.com/guangheli/p/11086708.html