比赛 NOIP模拟赛by mzx Day2 评测结果 AAAAAAAAAA
题目名称 学姐的巧克力盒 最终得分 100
用户昵称 前鬼后鬼的守护 运行时间 6.031 s
代码语言 C++ 内存使用 112.86 MiB
提交时间 2016-10-21 10:27:53
显示代码纯文本
#include<cstdio>
#define FILE "chocolatebox"

namespace IO{
	char buf[1<<15],*fs,*ft;
	inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
	inline int read(){
		int x=0,ch=getc();
		while(ch<'0'||ch>'9')ch=getc();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getc();}
		return x;
	}
}using namespace IO;

namespace Operation{
	int P;
	inline int add(int a,int b){return (a+=b)>=P?a-P:a;}
	inline int sub(int a,int b){return (a-=b)<0?a+P:a;}
	inline int mul(int a,int b){return 1LL*a*b%P;}
	inline int pow(int a,int b){int c=1;for(;b;b>>=1,a=mul(a,a))if(b&1)c=mul(c,a);return c;}
	inline int inv(int a){return pow(a,P-2);}
}using namespace Operation;

const int MAXN(1000010);

int n,m,K,p1,p2,ep2,a[MAXN];

namespace Segment_Tree{
	int L,t1[MAXN*2],t2[MAXN*2];
	
	inline int bitcount(int x){int c=0;for(;x;x>>=1)c+=x&1;return c;}
	void build(int* t){
		t[L]=1;
		for(int i=1;i<=n;i++)
			t[L+i]=a[i]%P;
		for(int i=n+1;i<L;i++)
			t[L+i]=1;
		for(int i=L-1;i;i--)
			t[i]=mul(t[i<<1],t[i<<1|1]);
	}
	void Build(){
		for(L=1;L-2<n;L<<=1);
		P=p1;build(t1);
		P=ep2;build(t2);
	}
	
	int query(int* t,int x,int y){
		int ans=1;
		for(int left=L+x-1,right=L+y+1;left^right^1;left>>=1,right>>=1){
			if(!(left&1))ans=mul(ans,t[left^1]);
			if(right&1)ans=mul(ans,t[right^1]);
		}
		return ans;
	}
	int Query(int ty,int x,int y){
		if(ty==1)return P=p1,query(t1,x,y);
		else{
			int e=(P=ep2,query(t2,x,y));
			return P=p2,pow(K,e);
		}
	}
	
	void Solve(){
		Build();
		for(int i=1;i<=m;i++){
			int ty=read(),x=read(),y=read();
			printf("%d\n",Query(ty,x,y));
		}
	}
}

namespace Math_Theory{
	const int MAXP(int(2e6));
	int p[MAXP+5],tot;bool np[MAXP+5];
	
	void Prime(){
		for(int i=2;i<=MAXP;i++){
			if(!np[i])
				p[++tot]=i;
			for(int j=1;j<=tot&&i*p[j]<=MAXP;j++){
				np[i*p[j]]=true;
				if(!(i%p[j]))break;
			}
		}
		ep2=1;int t=p2;
		for(int i=1;p[i]*p[i]<=p2&&t>1;i++)
			if(t%p[i]==0){
				ep2*=p[i]-1;
				for(t/=p[i];t%p[i]==0;t/=p[i])
					ep2*=p[i];
			}
		if(t>1)ep2*=t-1;
	}
	
	int y[10],t[10],num;
	int S[10][MAXN+5],IS[10][MAXN+5];
	
	inline int ex_gcd(int a,int b,int &x,int &y){
		if(!b)return x=1,y=0,a;
		int d=ex_gcd(b,a%b,x,y),t=x;
		return x=y,y=t-a/b*y,d;
	}
	
	void pretreat(int x){
		y[0]=x;
		for(int i=1;i<=tot&&x>1;i++)
			if(x%p[i]==0)
				y[++num]=p[i],x/=p[i];
		if(x>1)y[++num]=x;
		for(int k=1;k<=num;k++){
			int *s=S[k],*is=IS[k];
			P=y[k];s[0]=1;
			for(int i=1;i<=n;i++)
				s[i]=mul(s[i-1],a[i]);
			is[n]=inv(s[n]);
			for(int i=n;i;i--)
				is[i-1]=mul(is[i],a[i]);
			int mi=y[0]/y[k],YT;
			ex_gcd(mi,y[k],t[k],YT);
			t[k]%=y[k];if(t[k]<0)t[k]+=y[k];
			t[k]=1LL*t[k]*mi%y[0];
		}
		P=y[0];
	}
	
	int query(int l,int r){
		int ans=0;
		for(int i=1;i<=num;i++)
			ans=add(ans,mul(t[i],1LL*S[i][r]*IS[i][l-1]%y[i]));
		return ans;
	}
	
	void Solve(){
		static int POW[MAXP+5];
		if(p1)pretreat(p1);
		else{
			pretreat(ep2);
			POW[0]=1;P=p2;
			for(int i=1;i<ep2;i++)
				POW[i]=mul(POW[i-1],K);
			P=ep2;
		}
		for(int i=1;i<=m;i++){
			int ty=read(),x=read(),y=read(),q=query(x,y);
			printf("%d\n",ty==1?q:POW[q]);
		}
	}
}

void init(){
	n=read(),m=read(),K=read(),p1=read(),p2=read();
	Math_Theory::Prime();
	for(int *ai=a+1,*ed=a+n+1;ai!=ed;ai++)
		*ai=read();
}

int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);

	
	init();
	
	if(n<=500000)Segment_Tree::Solve();
	else Math_Theory::Solve();
	
	return 0;
}