比赛 |
NOIP模拟赛by mzx Day2 |
评测结果 |
AWAWTTTATT |
题目名称 |
学姐的巧克力盒 |
最终得分 |
30 |
用户昵称 |
Hzoi_chairman |
运行时间 |
12.418 s |
代码语言 |
C++ |
内存使用 |
48.38 MiB |
提交时间 |
2016-10-20 21:48:39 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define ll long long
ll mul(ll x,ll y,ll z){return (x*y-(ll)(x/(long double)z*y+1e-3)*z+z)%z;}
ll read()
{
ll x,f=1;
char ch;
while(ch=getchar(),!isdigit(ch))if(ch=='-')f=-1;
x=ch-48;
while(ch=getchar(),isdigit(ch))x=x*10+ch-48;
return x*f;
}
void write(ll x)
{
if(x<0)putchar('-'),x=-x;
int cnt=0;char ch[50];
while(ch[++cnt]=x%10+48,x/=10);
while(putchar(ch[cnt]),--cnt);
putchar('\n');
}
#define maxn 1001000
int prime[]={0,2,3,5,7,11,13,17,19,23,29};
ll s[maxn],a[maxn],inv[maxn],in[maxn],ss[maxn],ra[2000100],n,m,k,p1,p2;
void get_inv(ll a,ll b,ll & x,ll & y)
{
if(!b){x=1;y=0;return ;}
get_inv(b,a%b,x,y);
ll t=x;x=y;y=t-(a/b)*y;
}
ll power(ll x,ll n,ll mod)
{
ll ans=1;
while(n)
{
if(n&1)ans=mul(ans,x,mod);
x=mul(x,x,mod);
n>>=1;
}
return ans;
}
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
void build(int rt,int l,int r)
{
if(l==r)
{
ra[rt]=a[l];
return ;
}
build(lson);
build(rson);
ra[rt]=mul(ra[rt<<1],ra[rt<<1|1],p1);
}
ll query(int rt,int l,int r,int x,int y)
{
if(x<=l&&y>=r)return ra[rt];
ll ans=1;
if(x<=mid)ans=mul(ans,query(lson,x,y),p1);
if(y>mid)ans=mul(ans,query(rson,x,y),p1);
return ans;
}
int main()//第一问求出前缀积和逆元,第二问利用降幂大法
{
freopen("chocolatebox.in","r",stdin);
freopen("chocolatebox.out","w",stdout);
n=read(),m=read(),k=read(),p1=read(),p2=read();
ll _d=p2,y;
if(p2)for(int i=1;i<=10;i++)if(p2%prime[i]==0)_d=_d-_d/prime[i];
s[0]=1;inv[0]=1;in[0]=1;ss[0]=1;
for(int i=1;i<=n;i++)
{
a[i]=read();
if(p1==1000000007||p1==996919243)
{
s[i]=mul(s[i-1],a[i],p1);
get_inv(s[i],p1,inv[i],y);
inv[i]%=p1;
if(inv[i]<0)inv[i]+=p1;
}
if(p2)
{
ss[i]=mul(ss[i-1],a[i],_d);
get_inv(ss[i],_d,in[i],y);
in[i]%=_d;
if(in[i]<0)in[i]=_d;
}
}
if(p1&&p1!=1000000007&&p1!=996919243)build(1,1,n);
for(int i=1;i<=m;i++)
{
int type=read();
if(type==1)
{
int l=read(),r=read();
if(p1==1000000007||p1==996919243)write(mul(s[r],inv[l-1],p1));
else write(query(1,1,n,l,r));
}
else
{
int l=read(),r=read();
int x=mul(ss[r],in[l-1],_d);
int y=power(k,x+_d,p2);
write(y);
}
}
// system("pause");
fclose(stdin);
fclose(stdout);
}