CF1017F题解

这种板子题怎么能没有min25筛的题解呢???

题意:给定一个完全和性函数,求其前缀和。其实普通和性函数也能做就是了

\[\sum_{i=1}^n f(i) \]

类似积性函数,我们把这玩意儿在质数幂处的值之和

\[\sum_{i=1}^n \sum_{p^k|i,[\gcd(p^{k+1},i)=p^k]}kf(p) \]

\[\sum_pf(p)g(n,p) \]

其中 \(g(n,p)\)\(\sum_{i=1}^n \sum_k k[p^k|i \And gcd(p^{k+1},i)=p^k]\)

一个很明显的结论是 \(g(n,p)=n<p?g(\lfloor \frac n p \rfloor,p)+\lfloor \frac n p \rfloor\)

根号分治一下。当 \(n < p^2\) 时, \(g(n,p)=\lfloor \frac n p \rfloor\)

于是:

\[\sum_p^{\sqrt n}f(p)g(p)+\sum_{i=\sqrt n+1}^n \lfloor \frac n i \rfloor [\text {i is prime}]f(i) \]

后者相当于对于 \([1,\sqrt n]\) 中的 \(x\)\(\sum_{i=1}^{\lfloor \frac n x \rfloor}f(p)\)。因为 \(f\) 是一个多项式,所以我们相当于需要求出 \(\sum_p^{\lfloor \frac n x \rfloor} p^k\)

时间复杂度 $O(\frac {n^{\frac 3 4} } {\log n}) $,空间复杂度 $ O(\sqrt n)$。

但是 \(n \leq 3 \times 10^8\),而 \(\sum_{i=1}^n n^2=\frac {n(n+1)(2n+1)} 6\)\(6\) 在模 \(2^{32}\) 的意义下没有逆元,而 \(n^3\) 破了 \(2e25\),该怎么计算呢?

有一种办法是计算 \(3\) 在模 \(2^{32}\) 意义下的逆元,另一种办法是对 \(n\%3\) 的情况进行分类讨论。

这份代码在 CF 上面是 rk2,因为 rk1 是一个不讲武德的特判数据的人。。。

#include<cstdio>
#include<cmath>
typedef unsigned uint;
const uint M=17325;
uint pri[2000],p1[2000],p2[2000],p3[2000],s1[2000],s2[2000],s3[2000];
uint n,S,A,B,C,D,ans,top,id1[M],id2[M],pos[M];double invp[2000];
uint g0[M<<1],g1[M<<1],g2[M<<1],g3[M<<1];
inline uint f(const uint&n,const uint&p,const double&invp){
	return n<p?0:f(n*invp,p,invp)+(uint)(n*invp);
}
inline void Get(const uint&x,const uint&n){
	g0[x]=n;g1[x]=n*(n+1ull)/2;g3[x]=g1[x]*g1[x];
	g2[x]=n%3==1?g1[x]*(2ull*n+1)/3:((uint)(n*(n+1ull)/6))*(2ull*n+1);
	--g0[x];--g1[x];--g2[x];--g3[x];
}
inline void sieve(){
	register uint i,j,x;Get(1,n);
	for(i=2;i<=S;++i){
		Get(i,n/i);
		if(!pos[i]){
			pri[++top]=i;invp[top]=1./i+1e-15;pos[i]=top;
			s1[top]=s1[top-1]+(p1[top]=pri[top]);
			s2[top]=s2[top-1]+(p2[top]=pri[top]*p1[top]);
			s3[top]=s3[top-1]+(p3[top]=pri[top]*p2[top]);
			ans+=(A*p3[top]+B*p2[top]+C*p1[top]+D)*f(n,i,1./i+1e-15);
		}
		for(j=1;j<=top&&(x=i*pri[j])<=S;++j)if((pos[x]=j)==pos[i])break;
	}
	for(i=1;i<S;++i)Get(S+i,i);
	if(S*S!=n)Get(S<<1,i);
}
signed main(){
	register uint i,j,x,f,P1,P2,P3,S1,S2,S3;
	scanf("%u%u%u%u%u",&n,&A,&B,&C,&D);S=sqrt(n);f=S*S==n;sieve();
	for(i=1;i<=top;++i){
		P1=p1[i];P2=p2[i];P3=p3[i];S1=s1[i-1];S2=s2[i-1];S3=s3[i-1];
		for(j=1;(x=pri[i]*j)<=S;++j){
			g0[j]+=i-1-g0[x];
			g1[j]+=P1*(S1-g1[x]);
			g2[j]+=P2*(S2-g2[x]);
			g3[j]+=P3*(S3-g3[x]);
		}
		for(;pri[i]*(x=pri[i]*j)<=n&&j<=S;++j){
			x=n/x;
			g0[j]+=i-1-g0[S+x];
			g1[j]+=P1*(S1-g1[S+x]);
			g2[j]+=P2*(S2-g2[S+x]);
			g3[j]+=P3*(S3-g3[S+x]);
		}
		for(j=S-f;pri[i]*pri[i]<=j;--j){
			x=j*invp[i];
			g0[S+j]+=i-1-g0[S+x];
			g1[S+j]+=P1*(S1-g1[S+x]);
			g2[S+j]+=P2*(S2-g2[S+x]);
			g3[S+j]+=P3*(S3-g3[S+x]);
		}
	}
	g0[S+1]=top;g1[S+1]=s1[top];g2[S+1]=s2[top];g3[S+1]=s3[top];
	for(i=1;i<=S;++i){
		g3[i]-=g3[i+1];g2[i]-=g2[i+1];g1[i]-=g1[i+1];g0[i]-=g0[i+1];
		ans+=i*(A*g3[i]+B*g2[i]+C*g1[i]+D*g0[i]);	
	}
	printf("%u",ans);
}
posted @ 2022-01-11 14:03  Prean  阅读(48)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};