bzoj 3944 Sum
Description
Input
一共T+1行
第1行为数据组数T(T<=10)
第2~T+1行每行一个非负整数N,代表一组询问
Output
一共T行,每行两个用空格分隔的数ans1,ans2
Sample Input
6
1
2
8
13
30
2333
1
2
8
13
30
2333
Sample Output
1 1
2 0
22 -2
58 -3
278 -3
1655470 2
2 0
22 -2
58 -3
278 -3
1655470 2
杜教筛模板
对于ans1:
构造函数g,求出∑(f*g)(i)
$\sum_{i=1}^{n}(f*g)(i)=\sum_{i=1}^{n}\sum_{d|i}f(d)g(\frac{i}{d})=\sum_{ij<=n}f(i)g(j)=\sum_{i=1}^{n}g(i)F(\left \lfloor \frac{n}{i} \right \rfloor)$
所以有$g(1)F(n)=\sum_{i=1}^{n}(f*g)(i)-\sum_{i=2}^{n}g(i)F(\left \lfloor \frac{n}{i} \right \rfloor)$
因为有$$\sum_{d|i}\varphi(d)=i$$
所以构造g(x)=1
那么于是就有$F(n)=\sum_{i=1}^{n}i-\sum_{i=2}^{n}F(\left \lfloor \frac{n}{i} \right \rfloor)$
然后就可以杜教筛了
对于ans2则有$F(n)=1-\sum_{i=2}^{n}F(\left \lfloor \frac{n}{i} \right \rfloor)$
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<map> 7 using namespace std; 8 typedef long long lol; 9 const int N=6000000; 10 struct Node 11 { 12 lol phi,mu; 13 }ans; 14 lol mu[N+5],phi[N+5]; 15 int prime[N+5],tot; 16 bool vis[N+5]; 17 map<lol,lol> M1,M2; 18 void pre() 19 {int i,j; 20 mu[1]=1;phi[1]=1; 21 for (i=2;i<=N;i++) 22 { 23 if (vis[i]==0) 24 { 25 tot++; 26 prime[tot]=i; 27 mu[i]=-1; 28 phi[i]=i-1; 29 } 30 for (j=1;j<=tot;j++) 31 { 32 if (1ll*i*prime[j]>N) break; 33 vis[i*prime[j]]=1; 34 if (i%prime[j]==0) 35 { 36 mu[i*prime[j]]=0; 37 phi[i*prime[j]]=phi[i]*prime[j]; 38 break; 39 } 40 else 41 { 42 mu[i*prime[j]]=-mu[i]; 43 phi[i*prime[j]]=phi[i]*(prime[j]-1); 44 } 45 } 46 } 47 for (i=1;i<=N;i++) 48 phi[i]+=phi[i-1],mu[i]+=mu[i-1]; 49 } 50 Node query(lol n) 51 {lol s1,s2; 52 lol i,pos; 53 if (n<=N) return (Node){phi[n],mu[n]}; 54 if (M1[n]) 55 { 56 return (Node){M1[n],M2[n]}; 57 } 58 s1=0;s2=0; 59 for (i=2;i<=n;i=pos+1) 60 { 61 pos=n/(n/i); 62 Node p=query(n/i); 63 s2+=1ll*(pos-i+1)*p.mu; 64 s1+=1ll*(pos-i+1)*p.phi; 65 } 66 s1=((n+1)*n>>1)-s1; 67 s2=1-s2; 68 M2[n]=s2;M1[n]=s1; 69 return (Node){s1,s2}; 70 } 71 int main() 72 {int T; 73 lol n; 74 cin>>T; 75 pre(); 76 while (T--) 77 { 78 scanf("%lld",&n); 79 if (n<=N) 80 {ans.phi=phi[n];ans.mu=mu[n];} 81 else ans=query(n); 82 printf("%lld %lld\n",ans.phi,ans.mu); 83 } 84 }