hdu 4059 The Boss on Mars 容斥原理

容斥原理的题目,用容斥来做还是比较明显,关键是要去推那个4次方的公式。

然后注意公式里面要除以30,那么就先求%(mod*30),然后再除以30再%mod。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
const ll mod=1e9+7;
int a[1111],lon;
int n;

int get4(long long n)
{
//    cout<<n<<endl;
    ll now[10],sum=0;
    now[0]=1;
    for(int i=1;i<=5;i++)
    now[i]=(now[i-1]*n)%(mod*30);
    sum=(sum+mod*30-now[1])%(mod*30);
    sum=(sum+now[3]*10)%(mod*30);
    sum=(sum+now[4]*15)%(mod*30);
    sum=(sum+now[5]*6)%(mod*30);
    sum=(sum/30)%mod;
//    cout<<sum<<endl;
    return sum;
}

void geta()
{
    lon=0;
    int tmp=n;
    int sqr=sqrt((double)n);
    for(int i=2;i<=sqr+1&&tmp!=1;i++)
    {
        if(tmp%i==0)
        {
            a[++lon]=i;
            while(tmp%i==0) tmp/=i;
        }
    }
    if(tmp!=1)
    a[++lon]=tmp;
}

ll dfs(int t,int sum,ll now)
{
//    cout<<t<<endl;
    if(sum==0)
    {
        ll tmp=(get4(n/now));
        for(int i=1;i<=4;i++)
        tmp=(tmp*now)%mod;
        return tmp;
    }
    else if(t>lon) return 0;
    ll ret=0;
    ret=(ret+dfs(t+1,sum-1,now*a[t]))%mod;
    ret=(ret+dfs(t+1,sum,now))%mod;
    return ret;
}

int main()
{
//    freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        long long ans=get4(n);
        geta();
        for(int i=1;i<=lon;i++)
        {
//            cout<<i<<endl;
            ll ret=dfs(1,i,1);
            if(i%2) ans=(ans+mod-ret)%mod;
            else ans=(ans+ret)%mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(hdu 4059 The Boss on Mars 容斥原理)