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

 

 

 

你可能感兴趣的:(HDU)