洛谷 P7360 -「JZOI-1」红包(Min-Max 容斥+推式子)

洛谷题面传送门

hot tea.

首先注意到这个 \(\text{lcm}\) 特别棘手,并且这里的 \(k\) 大得离谱,我们也没办法直接枚举每个质因子的贡献来计算答案。不过考虑到如果我们把这里的 \(\text{lcm}\) 改为 \(\gcd\) 那么一遍莫比乌斯反演即可搞定,因此考虑将这里的 \(\text{lcm}\)\(\gcd\) 联系在一起。那么什么能将这两个东西联系在一起呢?Min-Max 容斥,具体来说,考虑式子

\[\text{lcm}(S)=\prod\limits_{\varnothing\ne T\subseteq S}\gcd(T)^{(-1)^{|T|-1}} \]

因此我们考虑开始推式子:

\[\begin{aligned} res&=\prod\limits_{i_1,i_2,\cdots,i_k}\text{lcm}(i_1,i_2,\cdots,i_k)\\ &=\prod\limits_{i_1,i_2,\cdots,i_k}\prod\limits_{S\subseteq\{1,2,3,\cdots,k\}}\gcd(\{i_x|x\in S\})^{(-1)^{|S|-1}}\\ &=\prod\limits_{j=1}^k\prod\limits_{|S|=j,S\subseteq\{1,2,3,\cdots,k\}}\prod\limits_{i_1,i_2,\cdots,i_k}\gcd(\{i_x|x\in S\})^{(-1)^{j-1}}\\ &=\prod\limits_{j=1}^k\prod\limits_{i_1,i_2,\cdots,i_j}\gcd(i_1,i_2,\cdots,i_j)^{(-1)^{j-1}·\dbinom{k}{j}·n^{k-j}}\\ &=\prod\limits_{j=1}^k\prod\limits_{d=1}^nd^{(-1)^{j-1}·\dbinom{k}{j}·n^{k-j}·\sum\limits_{i_1,i_2,\cdots,i_j}[\gcd(i_1,i_2,\cdots,i_j)=d]}\\ &=\prod\limits_{j=1}^k\prod\limits_{d=1}^nd^{(-1)^{j-1}·\dbinom{k}{j}·n^{k-j}·\sum\limits_{p=1}^{n/d}\mu(p)\lfloor\dfrac{n}{dp}\rfloor^j}\\ &=\prod\limits_{d=1}^n\prod\limits_{p=1}^n(d^{\mu(p)})^{\sum\limits_{j=1}^k(-1)^{j-1}·n^{k-j}·\lfloor\dfrac{n}{dp}\rfloor^j}\\ &=\dfrac{1}{\prod\limits_{d=1}^n\prod\limits_{p=1}^n(d^{\mu(p)})^{\sum\limits_{j=1}^k(-1)^{j}·n^{k-j}·\lfloor\dfrac{n}{dp}\rfloor^j}}\\ &=\dfrac{1}{\prod\limits_{d=1}^n\prod\limits_{p=1}^n(d^{\mu(p)})^{\sum\limits_{j=0}^k(-1)^{j}·n^{k-j}·\lfloor\dfrac{n}{dp}\rfloor^j-n^k}}\\ &=\dfrac{1}{\prod\limits_{d=1}^n\prod\limits_{p=1}^n(d^{\mu(p)})^{(n-\lfloor\dfrac{n}{dp}\rfloor)^k-n^k}}\\ &=\dfrac{1}{\prod\limits_{T=dp}f(T)^{(n-\lfloor\dfrac{n}{T}\rfloor)^k-n^k}} \end{aligned} \]

其中 \(f(T)=\prod\limits_{dp=T}d^{\mu(p)}\)

整除分块求解即可,注意,根据费马小定理,指数上那托东西要 \(\bmod 998244352\),而由于指数上面还套了一个快速幂,且这里的 \(k\) 很大,因此需要欧拉降幂,具体来说如果 \(k\le\varphi(998244352)\) 那么直接算即可,否则需令 \(k\leftarrow k\bmod\varphi(998244352)+\varphi(998244352)\)

时间复杂度 \(T\sqrt{n}\log n\)

const int MAXN=1e6;
const int MAXLEN=100;
const int MOD=998244353;
const int PHI=MOD-1;
const int PPHI=402653184;
int getmod(ll x){return (x>PPHI)?(x%PPHI+PPHI):x;}
int pr[MAXN+5],prcnt=0,mu[MAXN+5],prd[MAXN+5];
bool vis[MAXN+5];
int qpow(int x,int e){
	if(e<0) e+=PHI;int ret=1;
	for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
	return ret;
}
int _qpow(int x,int e){
	int ret=1;
	for(;e;e>>=1,x=1ll*x*x%PHI) if(e&1) ret=1ll*ret*x%PHI;
	return ret;
}
void sieve(int n){
	mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) mu[i]=-1,pr[++prcnt]=i;
		for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
			vis[pr[j]*i]=1;if(i%pr[j]==0) break;
			mu[pr[j]*i]=-mu[i];
		}
	}
	for(int i=1;i<=n;i++) prd[i]=1;
	for(int i=1;i<=n;i++) for(int j=1;j*i<=n;j++)
		prd[i*j]=1ll*prd[i*j]*qpow(i,mu[j])%MOD;
//	for(int i=1;i<=n;i++) printf("%d\n",prd[i]);
	prd[0]=1;
	for(int i=1;i<=n;i++) prd[i]=1ll*prd[i-1]*prd[i]%MOD;
}
int n;ll k;
char buf[MAXLEN+5];
void solve(){
	scanf("%d%s",&n,buf+1);k=0;int len=strlen(buf+1);
	for(int i=1;i<=len;i++) k=getmod(10ll*k+buf[i]-'0');
	int res=1;
	for(int l=1,r;l<=n;l=r+1){
		r=(n/(n/l));
		res=1ll*res*qpow(1ll*prd[r]*qpow(prd[l-1],MOD-2)%MOD,(_qpow(-n/l+n,k)-_qpow(n,k)+PHI)%PHI)%MOD;
	} printf("%d\n",qpow(res,MOD-2));
}
int main(){
	int qu;scanf("%d",&qu);sieve(MAXN);
	while(qu--) solve();
	return 0;
}
posted @ 2021-09-07 15:30  tzc_wk  阅读(73)  评论(0)    收藏  举报