比赛 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;
}