CodeForces - 615D Multipliers (欧拉降幂)

题目链接:点击这里

题目大意:
给定一个正整数 n n n ,求其所有约数的乘积,即求 ∏ d ∣ n d m o d    1 e 9 + 7 \prod\limits_{d|n}d \mod 1e9+7 dndmod1e9+7

题目分析:
n n n 用唯一分解定理展开 n = ∏ i = 1 x p i a i n=\prod_{i=1}^xp_i^{a_i} n=i=1xpiai ,逐个质数考虑贡献:
对于 p i a i p_i^{a_i} piai 来说,自己有 1 + 2 + . . . + a i = a i ⋅ ( a i + 1 ) 2 1+2+...+a_i=\frac{a_i·(a_i+1)}{2} 1+2+...+ai=2ai(ai+1) 种选法,对于剩余部分有 ∏ j = 1 x ( a j + 1 ) a i + 1 \frac{\prod_{j=1}^{x}(a_{j}+1)}{a_i+1} ai+1j=1x(aj+1) 种选法,所以该质数的贡献为 p i a i ⋅ ( a i + 1 ) 2 ⋅ ∏ j = 1 x ( a j + 1 ) a i + 1 = p i ∏ j = 1 x ( a j + 1 ) ⋅ a i 2 p_i^{\frac{a_i·(a_i+1)}{2}·\frac{\prod_{j=1}^{x}(a_{j}+1)}{a_i+1}}=p_i^{\frac{\prod_{j=1}^{x}(a_{j}+1)·a_i}{2}} pi2ai(ai+1)ai+1j=1x(aj+1)=pi2j=1x(aj+1)ai
由于指数很大需要用扩展欧拉定理降幂 a b ≡ a b % φ ( p ) + φ ( p ) m o d    p a^b\equiv a^{b\%\varphi(p)+\varphi(p)} \mod p abab%φ(p)+φ(p)modp
因为指数要除以 2 2 2 的所以我们可以在计算 ∏ j = 1 x ( a j + 1 ) ⋅ a i \prod_{j=1}^{x}(a_{j}+1)·a_i j=1x(aj+1)ai 的时候先模 2 φ ( p ) 2\varphi(p) 2φ(p) 以保证降幂的正确性
然后用快速幂把所有贡献乘起来即可

具体细节见代码:

// Problem: D - Multipliers
// Contest: Virtual Judge - 康复训练02
// URL: https://vjudge.net/contest/485549#problem/D
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int  ll
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
int read()
{
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,mul,res;
map<int,int>mp;
int qpow(int a,int b)
{
	int res = 1;
	while(b)
	{
		if(b&1) res = 1LL*a*res%mod;
		a = 1LL*a*a%mod;
		b >>= 1;
	}
	return res;
}
signed main()
{
	n = read();
	for(int i = 1;i <= n;i++)
	{
		int x = read();
		mp[x]++;
	}
	int sum = 1,res = 1;
	for(auto it:mp) sum = sum*(it.second+1)%(2*(mod-1));
	// cout<<sum<<endl;
	for(auto it:mp)
	{
		int val = it.first,cnt = it.second;
		res = res*qpow(val,sum*cnt/2%(mod-1)+mod-1)%mod;
	}
	cout<<res<<endl;
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值