比赛 |
NOIP模拟赛by mzx Day2 |
评测结果 |
WWWTWTTTTT |
题目名称 |
学姐的巧克力盒 |
最终得分 |
0 |
用户昵称 |
kito |
运行时间 |
13.835 s |
代码语言 |
C++ |
内存使用 |
191.03 MiB |
提交时间 |
2016-10-20 21:47:19 |
显示代码纯文本
#include<cstdio>
#include<cmath>
using namespace std;
#define fcl fclose(stdin); fclose(stdout); return 0
#define SUBMIT 2333
typedef long long LL;
LL n,m,K,p1,p2;
LL A[1000010];
inline LL Qmul(LL a,LL b,LL c){
return (a*b-(LL)(a/(long double)c*b+1e-3)*c+c)%c;
}
LL Qpow(LL a,LL b,LL p){
LL ans=1;
while(b){
if(b&1){
ans=Qmul(ans,a,p);
}
b>>=1;
a=Qmul(a,a,p);
}
return ans;
}
void work1(){
for(LL i=1;i<=n;++i){
scanf("%lld",&A[i]);
}
LL a,l,r,ans;
for(LL i=1;i<=m;++i){
scanf("%lld%lld%lld",&a,&l,&r);
if(a==1){
ans=1;
for(LL j=l;j<=r;++j){
ans=Qmul(ans,A[i],p1);
}
printf("%lld\n",ans);
}
else{
if(p2==1){
printf("0");
continue;
}
ans=1;
for(LL j=l;j<=r;++j){
ans=Qmul(ans,A[i],p2-1);
}
if(ans==0) ans=p2;
printf("%lld\n",Qpow(K,ans,p2));
}
}
}
/*********************************work2*************************************/
LL Pls[2][1000010],Inv[2][11][1000010];
LL Prime[3][100],tot1,tot2;
void ExGcd(LL a,LL b,LL& x,LL& y){
if(b==0){
x=1; y=0;
return;
}
ExGcd(b,a%b,x,y);
LL t=x;
x=y; y=t-(a/b)*y;
}
LL Gcd(LL a,LL b){
LL c;
while(a%b){
c=a%b;
a=b; b=c;
}
return b;
}
LL GetLcm(LL a,LL b){
LL c=Gcd(a,b);
return a/c*b;
}
LL AA[15],PP[15];
void Union(LL i){
LL x,y,j=i-1;
if(AA[i]>AA[j]){
LL d=Gcd(PP[j],PP[i]),c=(AA[i]-AA[j]),a=PP[j],b=PP[i];
c/=d; a/=d; b/=d;
ExGcd(a,b,x,y);
PP[i]=GetLcm(PP[i],PP[j]);
x%=PP[i]; c%=PP[i];
x=Qmul(x,c,PP[i]);
if(x<=0LL){
x=(x+(((-x)/b)+2LL)*b)%b;
}
x%=PP[i];
AA[i]=Qmul(x,PP[j],PP[i])+AA[j];
AA[i]%=PP[i];
}
else if(AA[i]<AA[j]){
LL d=Gcd(PP[j],PP[i]),c=(AA[j]-AA[i]),a=PP[i],b=PP[j];
c/=d; a/=d; b/=d;
ExGcd(a,b,x,y);
LL k=GetLcm(PP[i],PP[j]);
x%=k; c%=k;
x=Qmul(x,c,k);
if(x<=0LL){
x=(x+(((-x)/b)+2LL)*b)%b;
}
x%=k;
AA[i]=Qmul(x,PP[i],k)+AA[i];
PP[i]=k;
AA[i]%=PP[i];
}
else{
PP[i]=GetLcm(PP[i],PP[j]);
AA[i]%=PP[i];
}
}
LL SingleDog1(LL l,LL r){
for(int i=0;i<tot1;++i){
AA[i]=Qmul(Pls[1][r],Inv[1][i][l-1],p1);
PP[i]=p1;
}
for(int i=1;i<tot1;++i){
Union(i);
}
return AA[tot1-1];
}
LL SingleDog2(LL l,LL r){
for(int i=0;i<tot2;++i){
AA[i]=Qmul(Pls[0][r],Inv[0][i][l-1],p2);
PP[i]=p2;
}
for(int i=1;i<tot2;++i){
Union(i);
}
return AA[tot2-1];
}
void Query1(LL l,LL r){
LL a=SingleDog1(l,r);
printf("%lld\n",a);
}
void Query2(LL l,LL r){
LL a=SingleDog2(l,r);
if(a==0) a=p2+1;
printf("%lld\n",Qpow(K,a,p2+1));
}
void GetDiv(){
LL x=(LL)sqrt(double(p1)),P=p1;
for(LL i=2;i<=x;++i){
if(P%i==0){
Prime[1][tot1++]=1;
while(P%i==0){
P/=i;
Prime[1][tot1]*=i;
}
}
if(P==1) break;
}
if(P!=1){
Prime[1][tot1++]=P;
}
x=(LL)sqrt(double(p2)); P=p2;
for(LL i=2;i<=x;++i){
if(P%i==0){
Prime[0][tot2++]=1;
while(P%i==0){
P/=i;
Prime[0][tot2]*=i;
}
}
if(P==1) break;
}
if(P!=1){
Prime[0][tot2++]=P;
}
}
void work2(){
p2--;
GetDiv();
Pls[1][0]=Pls[0][0]=1;
for(int i=0;i<=10;++i){
Inv[1][i][0]=Inv[0][i][0]=1;
}
LL y;
for(LL i=1;i<=n;++i){
scanf("%lld",&A[i]);
if(p1){
Pls[1][i]=Qmul(Pls[1][i-1],A[i],p1);
for(int j=0;j<tot1;++j){
ExGcd(Pls[1][i],p1,Inv[1][j][i],y);
}
}
if(p2){
Pls[0][i]=Qmul(Pls[0][i-1],A[i],p2);
for(int j=0;j<tot2;++j){
ExGcd(Pls[0][i],p1,Inv[0][j][i],y);
}
}
}
LL a,l,r;
for(LL i=1;i<=m;++i){
scanf("%lld%lld%lld",&a,&l,&r);
if(a==1){
if(p1==1){
printf("0\n");
continue;
}
Query1(l,r);
}
else{
if(p2==0){
printf("0\n");
continue;
}
Query2(l,r);
}
}
}
/*********************************work2*************************************/
int main(){
#ifdef SUBMIT
freopen("chocolatebox.in","r",stdin);
freopen("chocolatebox.out","w",stdout);
#endif
scanf("%lld%lld%lld%lld%lld",&n,&m,&K,&p1,&p2);
if(n<=1000&&m<=1000){
work1();
}
else{
work2();
}
#ifndef SUBMIT
getchar(); getchar();
#endif
fcl;
}