hdu 4059 The Boss on Mars 容斥原理

思路:

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……)……;

具体看代码:

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<vector>
 8 #define ll long long
 9 #define pi acos(-1.0)
10 #define MAX 1000001
11 #define mod 1000000007
12 using namespace std;
13 ll prime[MAX],cnt,fac[MAX],num,n;
14 ll ans1,res,inv;
15 bool f[MAX];
16 void init()
17 {
18     ll i,j;
19     cnt=0;
20     for(i=2;i<MAX;i++){
21         if(f[i]==0){
22             prime[cnt++]=i;
23             for(j=i*i;j<MAX;j+=i)
24                 f[j]=1;
25         }
26     }
27 }
28 ll pows(ll a,ll b)
29 {
30     ll ans=1;
31     while(b){
32         if(b&1) ans=ans*a%mod;
33         b>>=1;
34         a=a*a%mod;
35     }
36     return ans%mod;
37 }
38 ll cal(ll m)
39 {
40     ll ans=(((6*pows(m,5)%mod+15*pows(m,4)%mod)%mod+10*pows(m,3)%mod)%mod-m+mod)%mod;
41     if(ans<0) ans=(ans%mod+ans)%mod;
42     ans=ans*inv%mod;
43     return ans;
44 }
45 void factor(ll m)
46 {
47     num=0;
48     for(int i=0;i<cnt&&prime[i]*prime[i]<=m;i++){
49         if(m%prime[i]==0){
50             fac[num++]=prime[i];
51             m/=prime[i];
52             while(m%prime[i]==0){
53                 m/=prime[i];
54             }
55         }
56     }
57     if(m>1) fac[num++]=m;
58 }
59 void dfs(ll a,int m,int c)
60 {
61     if(a>=n) return ;
62     ll t=(ll)(n-1)/a;
63     ans1=(ans1+c*pows(a,4)%mod*cal(t)%mod)%mod;
64     if(ans1<0) ans1=(ans1%mod+mod)%mod;
65     for(int i=m+1;i<num;i++)
66         dfs((ll)a*fac[i],i,-c);
67 }
68 int main(){
69     int t;
70     init();
71     scanf("%d",&t);
72     inv=pows(30,mod-2);
73     while(t--){
74         scanf("%lld",&n);
75         if(n==1){
76             printf("1\n");
77             continue;
78         }
79         factor(n);
80         ans1=0;
81         for(int i=0;i<num;i++)
82             dfs(fac[i],i,1);
83         res=cal(n-1);
84         res-=ans1;
85         while(res<0) res=(res%mod+mod)%mod;
86         printf("%lld\n",res);
87     }
88     return 0;
89 }
View Code

 

 

 

posted @ 2013-08-30 20:29  _随心所欲_  阅读(202)  评论(0编辑  收藏  举报