Loading

P4464 JZPKIL 题解

又是一道独立(基本上是)做出的黑,好耶!注:下文为了简洁除法用 / 代替分数。


前置知识:伯努利数求自然数幂和。

伯努利数:\(B_0=1,\sum\limits_{i=0}^n\dbinom{n+1}{i}B_i=0(n\ge1)\),于是可以 \(O(n^2)\) 预处理前 \(n\) 个伯努利数。

有结论:\(\sum\limits_{i=1}^{n-1}i^k=\dfrac{1}{k+1}\sum\limits_{i=1}^{k+1}\dbinom{k+1}{i}B_{k+1-i}n^i\)

于是 \(s_k(n)=\sum\limits_{i=1}^{n}i^k=\dfrac{1}{k+1}\sum\limits_{i=1}^{k+1}\dbinom{k+1}{i}B_{k+1-i}n^i+n^k\)\(s_k\) 是一个关于 \(n\)\(k+1\) 次多项式。于是我们可以 \(O(N^2)\) 预处理出 \(k\le N\)\(s_k\) 的每项系数。


推式子:

\( \begin{aligned} &\quad\sum\limits_{i=1}^n (i,n)^x((ni)/(i,n))^y=n^y\sum\limits_{i=1}^n (i,n)^{x-y}i^y\\ &=n^y\sum\limits_{d\mid n}d^{x-y}\sum\limits_{i=1}^n i^y[(i,n)=d]=n^y\sum\limits_{d\mid n}d^{x-y}\sum\limits_{i=1}^{n/d} (id)^y[(i,n/d)=1]\\ &=n^y\sum\limits_{d\mid n}d^x\sum\limits_{i=1}^{n/d} i^y\sum\limits_{D\mid (i,n/d)}\mu(D)=n^y\sum\limits_{d\mid n}d^x\sum\limits_{D\mid n/d}\mu(D)D^y\sum\limits_{i=1}^{n/Dd} i^y\\ &=n^y\sum\limits_{D\mid n}\mu(D)D^y\sum\limits_{d\mid n/D}(Dd/D)^xs(n/dD)=n^y\sum\limits_{D\mid n}\mu(D)D^{y-x}\sum\limits_{Dd\mid n}(Dd)^xs(n/Dd) \end{aligned} \)


其中 \(s(x)=\sum\limits_{i=1}^x i^y\),就是自然数幂和。接下来我们套路性的令 \(T=Dd\)

\(n^y\sum\limits_{D\mid n}\mu(D)D^{y-x}\sum\limits_{Dd\mid n}(Dd)^xs(n/Dd)=n^y\sum\limits_{T\mid n}T^xs(n/T)\sum\limits_{D\mid T} \mu(D)D^{y-x}\)

我们可以把 \(s\) 用前置知识拆成多项式,令 \(s(n)=\sum\limits_{i=1}^{y+1}a_in^i\),则

\(n^y\sum\limits_{T\mid n}T^xs(n/T)\sum\limits_{D\mid T} \mu(D)D^{y-x}=n^y\sum\limits_{i=1}^{y+1}a_i\sum\limits_{T\mid n}T^x(n/T)^{i}\sum\limits_{D\mid T} \mu(D)D^{y-x}=n^y\sum\limits_{i=1}^{y+1}a_in^i\sum\limits_{T\mid n}T^{x-i}\sum\limits_{D\mid T} \mu(D)D^{y-x}\)


注意到 \(a_in^i\) 后面很积性啊,有结论:若 \(f\) 为积性函数,\(n\) 质因数分解为:\(n=\prod\limits_{i=1}^kp_i^{\alpha_i}\),则:

\(g(n)=\sum\limits_{d\mid n}f(d)=\prod\limits_{i=1}^k\left(\sum\limits_{j=0}^{\alpha_i} f(p_i^j)\right)\),也是个积性。

考虑素数幂处的值(可以用 FFT 中的点值来理解下面)

\(f(n)=\sum\limits_{d\mid n} \mu(d)d^{y-x}\) 为积性函数,则对每个 \(n\) 的素数幂因子,\(f(p^\alpha)\) 是可以快速预处理的。

\(\sum\limits_{T\mid n}T^{x-i}\sum\limits_{D\mid T} \mu(D)D^{y-x}=\sum\limits_{T\mid n}T^{x-i}f(T)=\prod\limits_{i=1}^k\left(\sum\limits_{j=0}^{\alpha_i} p_i^{j(x-i)}f(p_i^j)\right)\)

这就很好算啦!先 Pollard-Rho 分解质因子,而后枚举原式中的 \(i\),对于每个 \(n\) 的素因子计算后面那坨即可,注意 \(f\) 不受原式 \(i\) 的影响,于是只用预处理一次即可,当然这是常数优化。

复杂度:\(O(T(n^{1/4}+yw(n)\log n))\),其中 \(w(n)\)\(n\) 的质因子个数,为 \(O(\log n)\) 级别。

几乎没怎么优化就跑得很快,目前谷 rk3。代码:

#include<bits/stdc++.h>
#define P pair<int,int>
#define fi first
#define se second
#define LL long long
#define bll __int128
#define fr(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
mt19937 rnd(time(0));
const int N=3e3+5,M=N-5,mod=1e9+7;
int T,B[N],jc[N],inv[N],I[N],a[N][N],x,y,pw,ans;LL n;
inline int md(int x){return x>=mod?x-mod:x;}
inline int ksm(int x,int p){int s=1;for(;p;(p&1)&&(s=1ll*s*x%mod),x=1ll*x*x%mod,p>>=1);return s;}
inline int C(int n,int m){return 1ll*jc[n]*inv[m]%mod*inv[n-m]%mod;}
int t,c[95],f[95][95],g[95][95];LL PP[95];
namespace PRHO
{
	#define mytz __builtin_ctzll
	#define Abs(x) ((x)>0?(x):-(x))
	inline LL gcd(LL a,LL b)
	{
		LL az=mytz(a),bz=mytz(b),z=min(az,bz),diff;b>>=bz;
		while(a) a>>=az,diff=a-b,az=mytz(diff),b=min(a,b),a=Abs(diff);return b<<z;
	}
	inline LL ksm(LL x,LL p,LL mod){LL s=1;for(;p;(p&1)&&(s=(bll)s*x%mod),x=(bll)x*x%mod,p>>=1);return s;}
	const LL pr[]={2,3,5,7,11,13,17,19,23,29,31,37};
	inline bool check(LL a,LL p)
	{
		LL d=a-1,t=0;while(~d&1) d>>=1,t++;LL now=ksm(p,d,a);
		if(now==1||now==0||now==a-1) return 1;
		for(int i=0;i<t;i++)
		{
			now=(bll)now*now%a;
			if(now==1) return 0;
			if(now==a-1&&i!=t-1) return 1;
		}
		return 0;
	}
	inline bool pd(LL x)
	{
		if(x==1) return 0;
		for(LL i:pr)
		{
			if(x==i) return 1;
			if(x%i==0||!check(x,i)) return 0;
		}return 1;
	}
	#define f(x,c,n) (((bll)(x)*(x)+(c))%(n))
	inline LL Find(LL x)
	{
		LL t1=1ll*rnd()*rnd()%(x-1)+1,c=1ll*rnd()*rnd()%(x-1)+1,t2=f(t1,c,x),d,mul=1;
		for(int i=1;;i<<=1,t1=t2,mul=1)
		{
			for(int j=1;j<=i;j++)
			{
				t2=f(t2,c,x);
				mul=(bll)mul*Abs(t1-t2)%x;
				if(j%127==0){d=gcd(mul,x);if(d>1) return d;}
			}d=gcd(mul,x);
			if(d>1) return d;
		}
	}
	void po(LL x)
	{
		if(x==1) return;
		if(pd(x)) return PP[++t]=x,void();LL num=Find(x);
		while(x%num==0) x/=num;po(x),po(num);
	}
	inline void bk(LL x)
	{
		t=c[1]=0;po(x);sort(PP+1,PP+1+t);t=unique(PP+1,PP+1+t)-PP-1;
		for(int i=1;i<=t;c[++i]=0) while(x%PP[i]==0) c[i]++,x/=PP[i];
	}
}using PRHO::bk;
inline void sol1()
{
	for(int i=1;i<=t;i++) PP[i]%=mod;
	for(int i=1;i<=t;i++)
	{
		int w=ksm(PP[i],pw);
		for(int j=f[i][0]=1,s=w;j<=c[i];j++,s=1ll*s*w%mod)
			f[i][j]=f[i][j-1],(j<=1)&&(f[i][j]=md(f[i][j]-s+mod));
	}
}
inline int sol2(int i)
{
	int PW=(x-i+mod-1)%(mod-1),ans=1;
	for(int i=1,w=ksm(PP[1],PW);i<=t;w=ksm(PP[++i],PW))
		for(int j=0,s=1;j<=c[i];j++,s=1ll*s*w%mod) g[i][j]=1ll*f[i][j]*s%mod;
	for(int i=1,s=0;i<=t;i++,ans=1ll*ans*s%mod,s=0) for(int j=0;j<=c[i];j++) s=md(s+g[i][j]);
	return ans;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>T;
	for(int i=jc[0]=1;i<=M+1;i++) jc[i]=1ll*jc[i-1]*i%mod;
	inv[M+1]=ksm(jc[M+1],mod-2);for(int i=M;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
	I[1]=1;for(int i=2;i<=M+1;i++) I[i]=mod-1ll*(mod/i)*I[mod%i]%mod;
	for(int i=B[0]=1;i<=M;i++)
	{
		for(int j=0;j<i;j++) B[i]=(B[i]+1ll*B[j]*C(i+1,j))%mod;
		B[i]=md(mod-1ll*I[i+1]*B[i]%mod);
	}
	for(int i=0;i<=M;a[i][i]++,i++) for(int j=0;j<=i;j++) a[i][i+1-j]=1ll*B[j]*C(i+1,j)%mod*I[i+1]%mod;
	while(T--)
	{
		cin>>n>>x>>y;bk(n);pw=(y-x+mod-1)%(mod-1);sol1();ans=0;
		for(int i=1;i<=y+1;i++) ans=(ans+1ll*a[y][i]*ksm(n%mod,i)%mod*sol2(i))%mod;
		cout<<(1ll*ans*ksm(n%mod,y)%mod)<<"\n";
	}
	return 0;
}
posted @ 2023-08-25 11:36  HaHeHyt  阅读(27)  评论(0编辑  收藏  举报