1. 程式人生 > >codeforce338 D. Multipliers 費馬小定理降冪

codeforce338 D. Multipliers 費馬小定理降冪

給定組成一個數的質因子序列,求其所有因子的乘積

一個質因子p的貢獻為(p^1p^2p^3...p^c)*(c1+1)(c2+1)...(cn+1)/(c+1)

化簡得                    \prod_{i=1}^{m}(p^{(1+c)*c/2})^{mul/(c+1)}=\prod_{i=1}^{m}p^{c*mul/2}

由於c*mul/2可能為一個大數,根據費馬小定理 p^{x\%(mod-1)} \equiv 1(mod)進行降所以對

所以對c*mul/2mod-1但是mul可能很大,需要在計算過程中不斷取模,

mul\%(mod-1)*c/2\ =?=\ c*mul/2\%(mod-1)

因為除法不滿足取模性質,所以不可以直接外提,且mod-1不是質數,2不存在逆元,考慮將模數擴大2倍消除其影響mod*2-2

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+5;
const long long MOD=1e9+7;
int n,a[MAX];
map<int,long long>mp;
map<int,long long>::iterator p;
long long pow(long long a,int k,long long mod)
{
    long long b=1;
    while(k)
    {
        if(k&1) b=b*a%mod;
        a=a*a%mod;
        k>>=1;
    }
    return b;
}
int main()
{
    long long x;
    while(~scanf("%d",&n))
    {
        mp.clear();
        for(int i=0;i<n;++i)
        {
            scanf("%d",&x);
            if(mp.find(x)!=mp.end()) ++mp[x];
            else mp[x]=1;
        }
        long long x=1;
        for(p=mp.begin();p!=mp.end();++p)
            x=x*(p->second+1)%(MOD*2-2);
        long long mul=1;
        for(p=mp.begin();p!=mp.end();++p)
        {
            mul=mul*pow(p->first,(x*p->second/2)%(MOD-1),MOD)%MOD;
        }
        printf("%lld\n",mul);
    }
    return 0;
}