[BZOJ3944]Sum(杜教筛)
2018-05-15 23:21
309 查看
3944: Sum
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 6201 Solved: 1606
[Submit][Status][Discuss]Description
Input
一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问
Output
一共T行,每行两个用空格分隔的数ans1,ans2
Sample Input
6
1
2
8
13
30
2333Sample Output
1 1
2 0
22 -2
58 -3
278 -3
1655470 2
HINT
Source
[Submit][Status][Discuss]
最基础的杜教筛。
杜教筛实际上就是这样一个式子:$$F(n)=H(n)-\sum\limits_{i=2}^{n}g(i)F(\lfloor\frac{n}{i}\rfloor)$$
设要求的是$f$的前缀和,辅助函数分别是$g$和$h$,$F$,$G$,$H$分别是三个函数的前缀和,如果能在$O(1)$的时间内求出$G$和$H$,就能在$O(n^{\frac{3}{4}})$内求出$F$。复杂度$O(\sum\limits_{i=1}^{\sqrt{n}} \sqrt{\frac{n}{i}})=O(n^\frac{4}{3})$,通过预处理前$n^{\frac{2}{3}}$个数就可以做到$O(n^{\frac{2}{3}})$了。
对于后面的$F(n)$值数组下标不可能直接记录,但是注意到我们最终需要的$F$函数值最多有$O(n^{\frac{2}{3}})$个(因为$\lfloor \frac{\lfloor\frac{a}{b}\rfloor}{c} \rfloor=\lfloor \frac{a}{bc} \rfloor$),所以对于后面的值可以把$x$存到$n/x$里。
回到这题,不要爆int就好了。
#include<cstdio> #include<cstring> #include<algorithm> #define rep(i,l,r) for (int i=l; i<=r; i++) typedef long long ll; using namespace std; const int N=2000010,M=100010; int T,n,m,tot,p ; ll phi ,mu ,Phi[M],Mu[M]; bool vis[M]; ll getphi(int x){ if (x<=m) return phi[x]; else return Phi[n/x]; } ll getmu(int x){ if (x<=m) return mu[x]; else return Mu[n/x]; } void solve(int x){ if (x<=m) return; int t=n/x,lst=1; ll p1=0,p2=0; if (vis[t]) return; vis[t]=1; Phi[t]=(1ll*x+1)*x>>1; Mu[t]=1; while (lst<x){ int i=lst+1; lst=x/(x/i); solve(x/i); p1+=getphi(x/i)*(lst-i+1); p2+=getmu(x/i)*(lst-i+1); } Phi[t]-=p1; Mu[t]-=p2; } int main(){ freopen("bzoj3944.in","r",stdin); freopen("bzoj3944.out","w",stdout); scanf("%d",&T); m=2000000; phi[1]=mu[1]=1; rep(i,2,m){ if (!phi[i]) p[++tot]=i,phi[i]=i-1,mu[i]=-1; for (int j=1; j<=tot && i*p[j]<=m; j++) if (i%p[j]==0) { phi[i*p[j]]=p[j]*phi[i]; mu[i*p[j]]=0; break; } else phi[i*p[j]]=(p[j]-1)*phi[i],mu[i*p[j]]=-mu[i]; } rep(i,2,m) phi[i]=phi[i-1]+phi[i],mu[i]=mu[i-1]+mu[i]; while (T--){ scanf("%d",&n); memset(vis,0,sizeof(vis)); if (n<=m) printf("%lld %lld\n",phi ,mu ); else solve(n),printf("%lld %lld\n",Phi[1],Mu[1]); } return 0; }
相关文章推荐
- bzoj 3944: Sum(杜教筛)
- bzoj 3944 Sum 杜教筛
- BZOJ.3944.Sum(杜教筛)
- BZOJ 3944: Sum [杜教筛]
- bzoj 3944: Sum -- 杜教筛
- [BZOJ 3944]Sum:杜教筛
- 【BZOJ 3944】sum 杜教筛
- bzoj 3944 sum 杜教筛
- bzoj3944 Sum 杜教筛
- bzoj 3944 Sum 杜教筛
- BZOJ_3944_Sum_杜教筛
- bzoj 3944: Sum (杜教筛)
- [bzoj3944]:Sum(杜教筛)
- [BZOJ3944]Sum(杜教筛)
- BZOJ3944: Sum 杜教筛
- [BZOJ3944]Sum-杜教筛
- bzoj3944 Sum 杜教筛
- 【BZOJ3944/4805】Sum/欧拉函数求和 杜教筛
- [杜教筛] BZOJ3944: Sum
- 杜教筛:Bzoj3944: sum