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