小Q與函式求和1
阿新 • • 發佈:2022-04-13
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)}\)
下面是被卡常的醜陋程式碼。題解區程式碼都被卡常了
#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; }