放松型休闲无脑小清新签到题

题目大意:

\(\sum_{i=1}^n\sum_{j=1}^n [gcd(i,j)是质数]*gcd(i,j)^k,1\leq n\leq 10^9,1\leq k\leq 100\)

题解:

\(f[x]=[x是质数]*x^k,F[x]=\sum_{i=1}^{x}f[i]\)
\(\sum_{i=1}^{n}\sum_{j=1}^{n}f[gcd(i,j)]=\sum_{d=1}^{n}f[d]\sum_{i=1}^{n}\sum_{j=1}^{n}[gcd(i,j)=d]\)
\(=\sum_{d=1}^{n}f[d]\sum_{i=1}^{ \left\lfloor{\frac{n}{d}}\right\rfloor}\sum_{j=1}^{ \left\lfloor{\frac{n}{d}}\right\rfloor}e[gcd(i,j)]=\sum_{d=1}^{n}f[d]\sum_{i=1}^{ \left\lfloor{\frac{n}{d}}\right\rfloor}\sum_{j=1}^{ \left\lfloor{\frac{n}{d}}\right\rfloor}\sum_{e|i,e|j}^{}μ[e]\)
\(=\sum_{d=1}^{n}f[d]\sum_{e=1}^{ \left\lfloor{\frac{n}{d}}\right\rfloor}{ \left\lfloor{\frac{n}{de}}\right\rfloor}^{2}=\sum_{(t=de)=1}^{n}{ \left\lfloor{\frac{n}{t}}\right\rfloor}^{2}\sum_{de=t}^{}f[d]*μ[e]\)
分块,需要求\(G[x]=\sum_{t=1}^{x}\sum_{de=t}^{}f[d]*μ[e]=\sum_{e=1}^{x}μ[e]\sum_{d=1}^{ \left\lfloor{\frac{x}{e}}\right\rfloor}f[d]\sum_{e=1}^{x}μ[e]F[\left\lfloor{\frac{x}{e}}\right\rfloor]\)
再分块,需要求\(F[x]\)
发现和质数有关,考虑\(Min25\)筛。初始时需要自然数幂和,要伯努利数。
另:为卡常,可预处理部分\(F[]\)或不用\(Map\)记忆化杜教筛。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int MOD=998244353;
int add(int a,int b)
{a+=b;return a>=MOD?a-MOD:a;}
int sub(int a,int b)
{a-=b;return a<0?a+MOD:a;}
int mul(int a,int b)
{return 1LL*a*b%MOD;}
int gcd(int a,int b)
{return b?gcd(b,a%b):a;}
int ksm(int a,int b)
{
	int ans=1;
	for(;b;b>>=1,a=mul(a,a))
		if(b&1)ans=mul(ans,a);
	return ans;
}
int n,k;
int s;
const int Q=1<<17;
int id1[Q],id2[Q],p[1<<18];
int ch[Q],mu[1<<20];
int tot=0;
int c[1<<7][1<<7];
int b[1<<7];
int f[Q];
int Gid(int x)
{return x<=s?id1[x]:id2[n/x];}
namespace Min25{
	int val[Q];
	int smf[Q];
	int inv[1<<7];
	int ch[1<<20]={0};
	void Prime(){
		int maxn=1e6;
		mu[1]=1;
		for(int i=2;i<=maxn;i++){
			if(!ch[i])p[++tot]=i,mu[i]=MOD-1;
			for(int j=1,t;j<=tot&&(t=i*p[j])<=maxn;j++){
				ch[t]=1;
				if(i%p[j]==0){
					mu[t]=0;
					break;
				}
				mu[t]=sub(0,mu[i]);
			}
		}
		for(int i=2;i<=maxn;i++)mu[i]=add(mu[i],mu[i-1]);
		for(int i=1;i<=tot;i++)
			if(p[i]>s){
				tot=i-1;
				return;
			}
	}
	void Bo(){
		for(int i=0;i<=123;i++){
			c[i][0]=1;
			for(int j=1;j<=i;j++)
				c[i][j]=add(c[i-1][j-1],c[i-1][j]);
		}
		b[0]=1;
		inv[1]=1;
		for(int i=1;i<=111;i++){
			int tmp=0;
			for(int j=0;j<i;j++)
				tmp=add(tmp,mul(c[i+1][j],b[j]));
			inv[i+1]=ksm(i+1,MOD-2);
			b[i]=mul(inv[i+1],sub(0,tmp));
		}
	}
	int Psum(int x){
		if(x<0){
			int als=0;
			for(int i=1;i<=x;i++)
				als=add(als,ksm(i,k));
			return als;
		}
		int als=0;
		x=(x+1)%MOD;
		for(int i=1,ow=x;i<=k+1;i++)
			als=add(als,mul(mul(c[k+1][i],b[k+1-i]),ow)),ow=mul(ow,x);
		return mul(inv[k+1],als);
	}
	void Init(){
		int maxn=0;
		Prime();Bo();
		for(int i=1,p1,p2;i<=n;i=p2+1)
		{
			p1=n/i,p2=n/p1;
			if(p1<=s)id1[p1]=++maxn;
			else id2[p2]=++maxn;
			val[maxn]=p1;
			f[maxn]=sub(Psum(p1),1);
		}
		for(int j=1;j<=tot;j++){
			int pr=p[j],owo=ksm(pr,k);
			smf[j]=add(smf[j-1],owo);
			for(int i=1;i<=maxn&&pr*pr<=val[i];i++)
				f[i]=sub(f[i],mul(owo,sub(f[Gid(val[i]/pr)],smf[j-1])));
		}
	}
}
int Res[1<<12];
int Gmu(int x)
{
	if(x<=1000000)return mu[x];
	if(Res[n/x])return Res[n/x]; 
	int als=0;
	for(int i=2,las;i<=x;i=las+1){
		las=x/(x/i);
		als=add(als,mul((las-i+1),Gmu(x/i)));
	}
	als=sub(1,als);
	return (Res[n/x]=als);
}
void Test(){
	int ppp;
	cin>>ppp;
	for(int i=1;i*i<=ppp;i++)
		if(ppp/(ppp/i)!=i)exit(0);
	Test();
}
int Gsum(int x)
{
	int als=0;
	for(int i=1,las;i<=x;i=las+1){
		las=x/(x/i);
		als=add(als,mul(sub(Gmu(las),Gmu(i-1)),f[Gid(x/i)]));
	}
	return als;
}
int main()
{
	cin>>n>>k;
	s=sqrt(n)+1;
	Min25::Init();
	int als=0;
	for(int i=1,las,lv=0,nv;i<=n;i=las+1){
		las=n/(n/i);
		nv=Gsum(las);
		als=add(als,mul(mul(n/i,n/i),sub(nv,lv)));
		lv=nv;
	}
	printf("%d",als);
	return 0;
}
posted @ 2019-02-20 21:31  蒟蒻小果冻  阅读(115)  评论(0编辑  收藏  举报