CF615D Multipliers 题解

分析

首先将 \(n\) 分解为 \(n= \prod_{i=1}^m p_i^{a_i}\)。那么 \(n\) 的约数个数为 \(d(n) = \prod_{i=1}^m (a_i +1)\)

考虑每个质因子的贡献。

首先对于 \(p_i\),它的整数次幂作为独立的一个约数时,一定有 \(p_i^1 p_i^2 \ldots p_i ^{a_i} = p_i^{\frac{a_i(a_i+1)}{2}}\)

其次,\(p_i\) 还可以和其他约数组合,方案数为 \(\frac{d(n)}{a_i +1}\)

那么 \(p_i\) 能够产生的贡献为 \((p_i^{\frac{a_i(a_i+1)}{2}})^{\frac{d(n)}{a_i+1}} = p_i^{\frac{a_i d(n)}{2}}\),其含义为 \(p_i\) 作为一个独立的约数时,也可以和其他约数相乘成为新的约数,且在其中 \(p_i\) 的贡献是相同的。

指数可能很大,咋办?欧拉降幂公式,由于 \(p_i\) 和模数 \(10^9 +7\) 都是质数,这里只写出底数与模数互质的形式 \[ a^b \equiv a^{b \, \bmod \, \varphi(p)} \pmod p \] 在本题里面,\(\varphi(10^9 +7) = 10^9 +6\)

\(d(n)\) 为奇数时,说明所有 \(a_i\) 都是偶数,那么可以直接将所有 \(a_i\) 除以 \(2\)

否则重新计算 \(\frac{d(n)}{2}\),方法是找到一个奇数指数 \(a_i\),然后乘上 \(\frac{a_i+1}{2}\) ,剩下的正常算即可。

CODE

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define _p first
#define _a second
const int N=2e5+5, mod=1e9+7;
int n, m, d=1, ans=1, a[N], p[N], v[N];
vector<pair<int,int> > vec;
int read() {
	int a=0, f=1; char c=getchar();
	while(!isdigit(c)) {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(isdigit(c)) a=a*10+c-'0', c=getchar();
	return a*f;
}
int fp(int x,int y) {
	int z=1; x%=mod;
	for(;y;x=x*x%mod,y>>=1) if(y&1) z=z*x%mod;
	return z;
}
signed main() {
	n=read();
	for(int i=1;i<=n;++i) ++v[read()];
	for(int i=1;i<=200000;++i) d=d*(v[i]+1)%(mod-1);
	for(int i=1;i<=200000;++i) if(v[i]) vec.push_back({i,v[i]});
	int fg=1;
	for(auto x:vec) {
		if(x._a&1) { fg=0; break; }
	}
	if(fg) {
		for(auto& x:vec) x._a/=2;
		for(auto x:vec) (ans*=fp(x._p,d*x._a%(mod-1)))%=mod; 
	} else {
		d=1;
		bool t=1;
		for(auto x:vec) {
			if(x._a&1&&t) t=0, d=d*(x._a+1)/2%(mod-1);
			else d=d*(x._a+1)%(mod-1);
		}
		for(auto x:vec) (ans*=fp(x._p,d*x._a%(mod-1)))%=mod; 
	} 
	printf("%lld\n",ans); 
}

CF615D Multipliers 题解
https://yozora0908.github.io/2022/cf615d-solution/
作者
yozora0908
发布于
2022年7月31日
许可协议