[BZOJ 2693]jzptab:莫比乌斯反演

点击这里查看原题

和BZOJ 2154类似,但是是多组数据,需要转化
http://blog.csdn.net/PoPoQQQ/article/details/42078725

(注意取模的问题,我因为输出答案时没有+mod%mod而WA了一次)

/*
User:Small
Language:C++
Problem No.:2693
*/
#include
#define ll long long
#define inf 999999999
using namespace std;
const int M=1e7+5;
const ll mod=1e8+9;
int n,m,mu[M],prime[M],cnt;
ll ans,h[M],sum[M];
bool not_prime[M];
ll getsum(int n,int m){
    n=(ll)n*(n+1)/2%mod;
    m=(ll)m*(m+1)/2%mod;
    return (ll)n*m%mod;
}
void solve(){
    ans=0;
    scanf("%d%d",&n,&m);
    if(n>m) swap(n,m);
    for(int i=1,r;i<=n;i=r+1){
        r=min(n/(n/i),m/(m/i));
        ans=(ans+(sum[r]-sum[i-1]+mod)%mod*getsum(n/i,m/i)%mod)%mod;
    }
    printf("%lld\n",(ans+mod)%mod);
}
int main(){
    freopen("data.in","r",stdin);//
    mu[1]=h[1]=1;
    for(int i=2;i<=1e7;i++){
        if(!not_prime[i]){
            prime[++cnt]=i;
            mu[i]=-1;
            h[i]=(i-(ll)i*i)%mod;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=1e7;j++){
            not_prime[i*prime[j]]=1;
            if(i%prime[j]==0){
                mu[i*prime[j]]=0;
                h[i*prime[j]]=h[i]*prime[j]%mod;
                break;
            }
            mu[i*prime[j]]=-mu[i];
            h[i*prime[j]]=h[i]*h[prime[j]]%mod;
        }
    }
    for(int i=1;i<=1e7;i++) sum[i]=(sum[i-1]+h[i])%mod;
    int t;
    scanf("%d",&t);
    while(t--) solve(); 
    return 0;
}

你可能感兴趣的:(BZOJ,莫比乌斯反演)