luoguP4449 于神之怒加强版

题意

默认\(n\leqslant m\)

一波莫反后可得:
\(\sum\limits_{T=1}^{n}\frac{n}{T}\frac{m}{T}\sum\limits_{d|T}d^k\mu(\frac{T}{d})\)

前面显然是可以除法分块的,后面是个积性函数,可以线性筛。

\(f(x)=\sum\limits_{d|x}d^k\mu(\frac{x}{d})\)

线性筛时\(i\)中不含\(prime_j\)自然好说,考虑\(i\)中含\(prime_j\)怎么办。

\(g(i)\)表示\(i\)中最小质因子(即\(prime_j\))的幂,即\(prime_j^k\)

\(i\not=g(i)\)\(i\)中的\(prime_j\)除去再算即可:
\(f(i*prime_j)=f(\frac{i}{g(i)})*f(g(i)*prime_j)\)
\(i=g(i)\)这时用上面的式子会出现: \(f(i*prime_j)=f(i*prime_j)*f(1)\)
这时考虑代回原式:
\(f(p^c)=\sum\limits_{d|p^c}d^k\mu(\frac{p^c}{d})\)
\(f(p^{c-1})=\sum\limits_{d|p^{c-1}}d^k\mu(\frac{p^{c-1}}{d})\)
发现\(f(p^c)=f(p^c)*(prime_j)^k+(f(1)^k*\mu(p^c))\)\(f(1)*\mu(p^c)=0\))。

于是就可以线性筛了,注意\(d^k\)也是积性函数。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5000010;
const ll mod=1000000007;
int T,K,n,m;
int mu[maxn],g[maxn];
ll pw[maxn],f[maxn],sum[maxn];
bool vis[maxn];
vector<int>prime;
inline ll power(ll x,ll k,ll mod)
{
	ll res=1;
	while(k)
	{
		if(k&1)res=res*x%mod;
		x=x*x%mod;k>>=1;
	}
	return res;
}
inline void pre_work(int n)
{
	vis[1]=1;f[1]=1;mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		//cerr<<i<<endl;
		if(!vis[i])prime.push_back(i),pw[i]=power(i,K,mod),f[i]=(pw[i]-1)%mod,g[i]=i,mu[i]=-1;
		for(unsigned int j=0;j<prime.size()&&i*prime[j]<=n;j++)
		{
			vis[i*prime[j]]=1;
			pw[i*prime[j]]=pw[i]*pw[prime[j]]%mod;
			if(i%prime[j]==0)
			{
				if(i==g[i])f[i*prime[j]]=f[i]*pw[prime[j]]%mod;//+(pw[1]*mu[i*prime[j]]=0);
				else f[i*prime[j]]=f[i/g[i]]*f[g[i]*prime[j]]%mod;
				g[i*prime[j]]=g[i]*prime[j];
				break;
			}
			f[i*prime[j]]=f[i]*f[prime[j]]%mod;
			g[i*prime[j]]=prime[j];
			mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=n;i++)sum[i]=(sum[i-1]+f[i])%mod;
}
inline ll solve(int n,int m)
{
	if(n>m)swap(n,m);
	ll res=0;
	for(int l=1,r;l<=n;l=r+1)
	{
		r=min(n/(n/l),m/(m/l));
		res=(res+1ll*(n/l)*(m/l)%mod*((sum[r]-sum[l-1])%mod+mod)%mod)%mod;
	}
	return (res%mod+mod)%mod;
}
int main()
{
	scanf("%d%d",&T,&K);
	pre_work(5000000);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		printf("%lld\n",solve(n,m));
	}
	return 0;
}
posted @ 2019-12-20 19:50  nofind  阅读(130)  评论(0编辑  收藏  举报