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

Sample Output

1 1
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 }

 


posted @ 2018-01-24 16:05  Z-Y-Y-S  阅读(241)  评论(0编辑  收藏  举报