【JZOJ B组】腐败

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);
}

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/83448030
今日推荐