欧拉降幂,基本计算定理——cf615D

 用基本算数定理求约数和的思想来计算,

首先用pi,ci来表示第i个质数,指数为i,然后对于每个pi,pi^2...都有指数为mul{(c_1+1)(c_2+1)(c_i-1+1)(c_i+1+1)...}的贡献,所以枚举累乘即可

注意要用欧拉降幂来计算质数,同时用中间挖掉一个值的累乘,可以预处理前缀后缀乘积来做

/*
枚举每个不同的质因子pi,枚举其指数[1,ci]
累乘每个pi^ci的贡献即可 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 200005
#define ll long long
#define mod 1000000007

ll n,a[N];
ll p[N],c[N],m;
ll suf[N],pre[N],ans;
ll Pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b%2)
            res=res*a%mod;
        b>>=1;a=a*a%mod;
    }
    return res;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        if(p[m]!=a[i]){
            p[++m]=a[i];
            c[m]=1;
        }    
        else c[m]++;
    } 
    
    suf[m+1]=1;pre[0]=1;
    for(ll i=m;i>=1;i--)
        suf[i]=suf[i+1]*(c[i]+1)%(mod-1);
    for(ll i=1;i<=m;i++)
        pre[i]=pre[i-1]*(c[i]+1)%(mod-1);
    
    ans=1;
    for(ll i=1;i<=m;i++){
        ll tmp=1;
        ll prod=pre[i-1]*suf[i+1]%(mod-1);
        for(ll j=1;j<=c[i];j++){
            tmp=tmp*p[i]%mod;
            ans=ans*Pow(tmp,prod)%mod;
        } 
    }
    cout<<ans<<endl;
}

 

posted on 2019-08-31 15:23  zsben  阅读(287)  评论(0编辑  收藏  举报

导航