【JZOJ B組】腐敗
阿新 • • 發佈:2018-11-01
Description
Input
第一行一個正整數n,表示序列長度
第二行n個正整數,為給出的序列A
Output
一個非負整數,為答案。
Sample Input
3
6 4 12
Sample Output
13824
Data Constraint
50%:n<=3000;
100%:n<=30000,A[i]<=10^7
思路
可以發現,每一個質因子的貢獻可以單獨拿出來算
求出每一個數有多少質因子p,然後兩兩配對(可以優化到O(能過))
最後會剩下一些較大的質數,我們可以排個序,若a[i]==a[i-1]則會產生貢獻
程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int maxn=3e4+77; const ll mod=100000000009; int a[maxn],b[maxn+77],c[maxn],cnt,z[maxn],n; ll ans=1; ll mult(ll x,ll t) { if(x<t) swap(x,t); ll p=0; while(t) { if(t&1) p=(p+x)%mod; t>>=1; x=(x+x)%mod; } return p; } ll power(ll x,ll t) { ll p=1; while(t) { if(t&1) p=mult(p,x)%mod; t>>=1; x=mult(x,x)%mod; } return p; } void init() { for(int i=2; i<=maxn; i++) { if(!b[i]) z[++cnt]=i; for(int j=1; j<=cnt; j++) { if(i*z[j]>maxn) break; b[i*z[j]]=1; if(i%z[j]==0) break; } } } int main() { init(); scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=cnt; i++) { memset(b,0,sizeof(b)); for(int j=1; j<=n; j++) { while(a[j]%z[i]==0) { a[j]/=z[i]; b[j]++; } } for(int j=1; j<=n; j++) c[b[j]]++; b[0]=0; for(int j=0; j<=50; j++) for(; c[j]; b[++b[0]]=j,c[j]--); ll sum=0; for(int j=1; j<=n; j++) sum+=1ll*b[j]*(n-j+1); ans=mult(ans,power(z[i],sum)); } sort(a+1,a+n+1); int p=1; for(int i=1; i<=n; i++) { if(a[i]!=a[i-1]) p=i; ans=mult(ans,power(a[i],i-p+1)); } printf("%lld",ans); }