您的位置:首页 > 其它

hdu 4059 The Boss on Mars 容斥原理

2013-08-30 20:29 501 查看
思路:

1.首先介绍下4次方的求和公式:S(n)=(6*n^5+15*n^4+10*n^3-n)/30.

2.n太大直接求1~n-1中与n互质的数会超时,那么就转换下思路,求不与n互质的数;

分析知道当某一个数不与n互质时,他的倍数也一定不与n互质,而且这个数与n具有公共的因子;

为了去掉重复的很容易想到容斥原理。

对于n=p1^a1*p2^a2*p3^a3……

与n不互质的数=(p1+2*p1……)+(p2+2*p2……)-(p1*p2+2*p1*p2……)……;

具体看代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<vector>
#define ll long long
#define pi acos(-1.0)
#define MAX 1000001
#define mod 1000000007
using namespace std;
ll prime[MAX],cnt,fac[MAX],num,n;
ll ans1,res,inv;
bool f[MAX];
void init()
{
ll i,j;
cnt=0;
for(i=2;i<MAX;i++){
if(f[i]==0){
prime[cnt++]=i;
for(j=i*i;j<MAX;j+=i)
f[j]=1;
}
}
}
ll pows(ll a,ll b)
{
ll ans=1;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans%mod;
}
ll cal(ll m)
{
ll ans=(((6*pows(m,5)%mod+15*pows(m,4)%mod)%mod+10*pows(m,3)%mod)%mod-m+mod)%mod;
if(ans<0) ans=(ans%mod+ans)%mod;
ans=ans*inv%mod;
return ans;
}
void factor(ll m)
{
num=0;
for(int i=0;i<cnt&&prime[i]*prime[i]<=m;i++){
if(m%prime[i]==0){
fac[num++]=prime[i];
m/=prime[i];
while(m%prime[i]==0){
m/=prime[i];
}
}
}
if(m>1) fac[num++]=m;
}
void dfs(ll a,int m,int c)
{
if(a>=n) return ;
ll t=(ll)(n-1)/a;
ans1=(ans1+c*pows(a,4)%mod*cal(t)%mod)%mod;
if(ans1<0) ans1=(ans1%mod+mod)%mod;
for(int i=m+1;i<num;i++)
dfs((ll)a*fac[i],i,-c);
}
int main(){
int t;
init();
scanf("%d",&t);
inv=pows(30,mod-2);
while(t--){
scanf("%lld",&n);
if(n==1){
printf("1\n");
continue;
}
factor(n);
ans1=0;
for(int i=0;i<num;i++)
dfs(fac[i],i,1);
res=cal(n-1);
res-=ans1;
while(res<0) res=(res%mod+mod)%mod;
printf("%lld\n",res);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: