小Q与函数求和1

https://ac.nowcoder.com/acm/contest/11171/E

给定 \(N,k\)\(1\le N\le 5\cdot 10^6,-1\le k\le 10^9\),求:

\[\sum_{i=1}^N\sum_{j=1}^N\varphi(ij\gcd(i,j)^k) \]

2s,512MB。

\[\begin{aligned} \sum_{i=1}^N\sum_{j=1}^N\varphi(ij\gcd(i,j)^k)&=\sum_{i=1}^N\sum_{j=1}^N\varphi(ij)\gcd(i,j)^k\\ &=\sum_{d=1}^N\sum_{i=1}^N\sum_{j=1}^N[\gcd(i,j)=d]d^k\frac{\varphi(i)\varphi(j)d}{\varphi(d)}\\ &=\sum_{d=1}^N\frac{d^{k+1}}{\varphi(d)}\sum_{i=1}^{\lfloor N/d\rfloor}\sum_{j=1}^{\lfloor N/d\rfloor}[\gcd(i,j)=1]\varphi(id)\varphi(jd)\\ &=\sum_{d=1}^N\frac{d^{k+1}}{\varphi(d)}\sum_{i=1}^{\lfloor N/d\rfloor}\sum_{j=1}^{\lfloor N/d\rfloor}\sum_{x|i\and x|j}\mu(x)\varphi(id)\varphi(jd)\\ &=\sum_{x=1}^N\sum_{d=1}^N\frac{d^{k+1}}{\varphi(d)}\left(\sum_{i=1}^{\lfloor N/d\rfloor}[x|i]\varphi(id)\right)^2\\ &=\sum_{x=1}^N\mu(x)\sum_{d=1}^N\frac{d^{k+1}}{\varphi(d)}\left(\sum_{i=1}^{\lfloor N/dx\rfloor}\varphi(idx)\right)^2\\ &=\sum_{T=1}^N\sum_{x|T} \mu(x)\frac{\left(\frac{T}{x}\right)^{k+1}}{\varphi\left(\frac{T}{x}\right)}\left(\sum_{i=1}^{\lfloor N/T\rfloor} \varphi(iT)\right)^2\end{aligned} \]

\(\mu(x)\frac{\left(T/x\right)^{k+1}}{\varphi\left(T/x\right)}\)\(\sum_{i=1}^{\lfloor N/T\rfloor} \varphi(iT)\) 都可以 \(\mathcal O(n\ln n)\) 预处理出,这道题就做完了

下面是被卡常的丑陋代码。题解区代码都被卡常了

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
const int N=5e6+10,mod=998244353;
int pri[N],phi[N],pw[N],cnt,k,n,mu[N],inv[N];
bool vis[N];
int qpow(int a,int n)
{
	int ans=1;
	while(n)
	{
		if(n&1)ans=a*ans%mod;
		a=a*a%mod;
		n>>=1;
	}
	return ans;
}
void sieve()
{
	pw[1]=1,phi[1]=1,mu[1]=1,inv[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(mu[i]==mod)mu[i]=0;
		if(!vis[i])pri[++cnt]=i,pw[i]=qpow(i,k+1),phi[i]=i-1,mu[i]=mod-1;
		for(int j=1;j<=cnt&&pri[j]*i<=n;j++)
		{
			int x=i*pri[j];
			vis[x]=1;
			pw[x]=pw[i]*pw[pri[j]]%mod;
			phi[x]=(pri[j]-1)*phi[i];
			mu[x]=mod-mu[i];
			if(i%pri[j]==0)
			{
				phi[x]=pri[j]*phi[i];
				mu[x]=0;
				break;
			}
		}
	}
}
int f[N],g[N];
void Add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
signed main()
{
	n=read(),k=read();sieve();
	inv[0]=inv[1]=1;for(int i=2;i<=n;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	int ans=0;
	for(int i=1;i<=n;i++)for(int j=1;j*i<=n;j++)
	{
		int x=i*j;
		Add(f[x],mu[i]*pw[j]%mod*inv[phi[j]]%mod),Add(g[i],phi[x]);
	}
	for(int i=1;i<=n;i++)Add(ans,f[i]*g[i]%mod*g[i]%mod);
	printf("%lld\n",ans);
	return 0;
}
posted @ 2022-04-13 19:50  zzt1208  阅读(79)  评论(1编辑  收藏  举报