您的位置:首页 > 其它

【NOIP模拟】腐败

2016-07-19 20:05 330 查看

Description



Solution

刚看到这种题,就想开始繁衍。。。。。。不对啊,这种东西怎么繁衍,并显示暴力加优化!

对每个数分解质因数,然后对每个因数开一个桶做,是不是很水。

怎么处理空间问题

可以动态开桶,但有一种更机智的方法。

因为如果有一个质数大于107−−−√,那么这些质数在一个数分解质因数是最多只会出现一次,那么我们就有很多的质数不用刻意再取开一个桶了,直接用一个数组统计起来就可以了。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=30007,da=10000000;
const ll mo=100000000009;
ll i,j,k,l,n,m,ans,tt;
int a[maxn],p[da],shu[da+1];
int t[4000][20],duo[4400];
bool bz[da];
ll gcd(ll x,ll y){
ll o=1;
while(o){
o=x%y;
x=y;
y=o;
}
return x;
}
ll qs(ll x,ll y){
ll z=0;
if(y==0)return z;
z=qs(x,y/2);
z=z*2%mo;
if(y%2==1)z=(z+x)%mo;
return z;
}
ll qsm(ll x,ll y){
ll z=1;
while(y){
if(y&1==1)z=qs(z,x)%mo;
x=qs(x,x)%mo;
y/=2;
}
return z;
}
ll suan(ll x,ll y){
ll z=(x-y+1);
return (z+x)*y/2;
}
int main(){
//  freopen("fan.in","r",stdin);
fo(i,2,sqrt(da)){
if(!bz[i])p[++p[0]]=i;
fo(j,1,p[0]){
tt=p[j]*i;if(tt>sqrt(da))break;bz[tt]=1;
}
}
scanf("%lld",&n);
ans=1;
fo(i,1,n){
scanf("%lld",&a[i]);
ans=qs(ans,a[i]);
if(ans==0){
ans=ans;
}
ll u=a[i];
fo(j,1,p[0]){
if(u==1)break;
if(u%p[j]==0){
ll y=0;
duo[j]++;
while(!(u%p[j]))u=u/p[j],y++;
t[j][y]++;
}
}
if(u>1){
if(shu[u])ans=qs(ans,qsm(u,shu[u]));
shu[u]++;
}
}
fo(i,1,p[0]){
ll o=1,d=0;
if(duo[i]==0)continue;
fo(j,1,20){
if(d==duo[i])break;
o=qs(o,p[i]%mo);
ans=qs(ans,qsm(o,suan(duo[i]-d-1,t[i][j])));
d+=t[i][j];
}
}
printf("%lld",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: