trainging contest#1(2011大连现场赛)I BY bly

来源:互联网 发布:前锦网络信息技术 编辑:程序博客网 时间:2024/04/28 04:15

先因式分解,记录所有的因子

然后直接容斥即可,四次方和公式:n*(n+1)*(2*n+1)*(3*n^2+3*n-1)/30

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const LL mod=1000000007;int vis[1000010],c;LL rev;int prime[1000000];LL pow_mod(LL n){    if(n==0) return 1;    LL ans=pow_mod(n/2);    ans=ans*ans%mod;    if(n%2==1) ans=ans*30%mod;    return ans;}void init(){    memset(vis,0,sizeof(vis));    c=0;rev=pow_mod(mod-2);    for(int i=2;i<=1000;i++) if(!vis[i])    {        for(int j=i*i;j<=1000000;j+=i) vis[j]=1;    }    for(int i=2;i<=1000000;i++) if(!vis[i])        prime[c++]=i;}LL getsum(LL x){    LL t1=(x*x%mod+x)%mod;    LL t2=(2*x%mod+1)%mod;    LL t3=((3*x)%mod*x%mod+3*x%mod-1+mod)%mod;    return ((t1*t2%mod)*t3%mod)*rev%mod;}LL getfour(LL x){    return ((x*x%mod)*x%mod)*x%mod;}int fac[100],f,n;int main(){    init();    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        int tmp=n;        f=0;        for(int i=0;i<c;i++)        {            if(tmp%prime[i]==0) fac[f++]=prime[i];            while(tmp%prime[i]==0) tmp/=prime[i];        }        if(tmp!=1) fac[f++]=tmp;        LL ans=getsum(n);        for(int i=1;i<(1<<f);i++)        {            int bitcount=0,a=1;            for(int j=0;j<f;j++) if(i&(1<<j))            {                a*=fac[j];                bitcount++;            }            LL t=getfour(a)*getsum(n/a)%mod;            if(bitcount%2==1) ans=(ans-t+mod)%mod;            else ans=(ans+t)%mod;        }        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击