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