HDU 4059 容斥初步练习

Posted on 2016-07-11 18:20  yyjxx2010xyu  阅读(145)  评论(0编辑  收藏  举报
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #define LL long long
 6 using namespace std;
 7 const LL Mod=1000000007;
 8 const LL Maxn=60010;
 9 LL Factor[35],cnt,n,m,tot,Rev,Kase,Prime[Maxn];
10 bool vis[Maxn];
11 
12 inline LL Quick_Pow(LL x,LL y)
13 {
14     LL Ret=1;
15     while (true)
16     {
17         if (y&1) Ret=(Ret*x)%Mod;
18         x=(x*x)%Mod; y>>=1;
19         if (y==0) break;
20     }
21     return Ret;
22 }
23 
24 inline void Make_Prime()
25 {
26     memset(vis,false,sizeof(vis));
27     for (LL i=2;i<Maxn;i++)
28     {
29         if (!vis[i]) Prime[++tot]=i;
30         for (LL j=1;j<=tot && Prime[j]*i<Maxn;j++) 
31         {
32             vis[Prime[j]*i]=true;
33             if (i%Prime[j]==0) break;
34         }
35     }
36 }
37     
38 inline LL Calc(LL N)
39 {
40     LL Ret=N;
41     Ret=(Ret*(N+1))%Mod;
42     Ret=(Ret*(2*N+1))%Mod;
43     Ret=(Ret*((3*N*N+3*N-1)%Mod))%Mod;
44     Ret=(Ret*Rev)%Mod;
45     return Ret;
46 }
47 inline void Get_Factor(LL P)
48 {
49     cnt=0;
50     for (LL i=1;i<=tot && Prime[i]<=P;i++)
51         if (P%Prime[i]==0)
52         {
53             Factor[++cnt]=Prime[i];
54             while (P%Prime[i]==0) P/=Prime[i];
55         }
56     if (P!=1) Factor[++cnt]=P;
57 }
58 inline LL Pow2(LL x) {return (x*x)%Mod;}
59 inline LL Pow4(LL x) {return (Pow2(x)*Pow2(x))%Mod;}
60 LL Dfs(LL d,LL start)
61 {
62     LL Ret=0;
63     for (LL i=start;i<=cnt;i++)
64     {
65         LL tmp=Pow4(Factor[i]);
66         Ret=(Ret+(tmp*Calc(d/Factor[i]))%Mod)%Mod;
67         Ret=(Ret-(tmp*Dfs(d/Factor[i],i+1))%Mod+Mod)%Mod;
68     }
69     return Ret;
70 }
71 inline LL Solve()
72 {
73     Get_Factor(n);
74     return ((Calc(n)%Mod)-(Dfs(n,1))%Mod+Mod)%Mod;
75 }
76 int main()
77 {
78     scanf("%lld",&Kase);
79     Rev=Quick_Pow(30,Mod-2);
80     Make_Prime();
81     
82     for (LL kase=1;kase<=Kase;kase++)
83     {
84         scanf("%lld",&n);
85         printf("%lld\n",Solve());
86     }
87     return 0;
88 }
HDU 4059

求的是与n互质的数的四次方的和。 首先四次方有个公式。把1~n的然后减去n的约数的四次方即可,这就需要用到容斥了。

Sum(2)-(Sum(2*3)+Sum(2*5)+Sum(2*7)..)+(Sum(2*3*5)+Sum(2*3*7)+Sum(3*5*7)..)-..