80分求助
查看原帖
80分求助
289230
ricky0916楼主2021/4/14 18:29
#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x;
}
void write(int x){
	if(x/10) write(x/10);
	putchar(x%10+'0');
}
void we(int x){
	write(x);
	putchar('\n');
}
int p,n,m,c,mod[110],gsm1[30][20010],gsm2[30][20010];
inline void mo(int &x){
	if(x>=p) x-=p;
}
inline int phi(int x){
	int ret=x;
	for(int i=2;i*i<=x;i++){
		if(x%i==0){
			while(x%i==0) x/=i;
			ret-=ret/i;
		}
	}
	if(x>1) ret-=ret/x;
	return ret;
}
void init(){
	mod[1]=p;
	for(int i=2;mod[i-1]>1;i++) mod[i]=phi(mod[i-1]);
	for(int i=1;mod[i]>1;i++){
		gsm1[i][0]=gsm2[i][0]=1;
		for(int j=1;j<=20000;j++){
			gsm1[i][j]=1ll*gsm1[i][j-1]*c%mod[i];
		}
		for(int j=1;j<=20000;j++){
			gsm2[i][j]=1ll*gsm2[i][j-1]*gsm1[i][20000]%mod[i];
		}
	}
}
int gsm(int idx,int x){
	return 1ll*gsm2[idx][x/20000]*gsm1[idx][x%20000]%mod[idx];
}
int val[200010],ls[50010],a[50010];
bool flag[200010];
inline void push_up(int rt){
	val[rt]=val[rt<<1]+val[rt<<1|1];
	mo(val[rt]);
	flag[rt]=flag[rt<<1]&flag[rt<<1|1];
}
inline int calc(int layer,int now,int ms){
	if(layer==0) return ms;
	if(c==1) return 1;
	if(c%mod[now]==0) return 0;
	if(c%mod[now]==1) return 1;
	if(layer>=6||(layer>=2&&c>=10)) return gsm(now,calc(layer-1,now+1,ms)+mod[now+1]);
	long long las=0,hhh=1;
	for(int i=0;i<ms;i++){
		hhh*=c;
		if(hhh>=mod[now]) return gsm(now,calc(layer-1,now+1,ms)+mod[now+1]);
	}
	if(layer==1) return hhh;
	for(int i=1;i<layer-1;i++){
		las=hhh;
		hhh=1;
		for(int j=0;j<las;j++){
			hhh*=c;
			if(hhh>=mod[now]) return gsm(now,calc(layer-1,now+1,ms)+mod[now+1]);
		}
	}
	return gsm(now,hhh);
}
void build(int rt,int l,int r){
	if(l==r){
		val[rt]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	push_up(rt);
}
void update(int rt,int l,int r,int ul,int ur){
	if(flag[rt]) return;
	if(ur<l||ul>r) return;
	if(l==r){
		ls[l]++;
		int tmp=calc(ls[l],1,a[l]);
		if(val[rt]==tmp) flag[rt]=1;
		val[rt]=tmp;
		return;
	}
	int mid=(l+r)>>1;
	update(rt<<1|1,mid+1,r,ul,ur);
	update(rt<<1,l,mid,ul,ur);
	push_up(rt);
}
int query(int rt,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r) return val[rt];
	if(qr<l||ql>r) return 0;
	int mid=(l+r)>>1;
	int ret=query(rt<<1,l,mid,ql,qr)+query(rt<<1|1,mid+1,r,ql,qr);
	mo(ret);
	return ret;
}
int opt,l,r;
int main(){
	n=read();
	m=read();
	p=read();
	c=read();
	init();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	for(int i=1;i<=m;i++){
		opt=read();
		l=read();
		r=read();
		if(opt) we(query(1,1,n,l,r));
		else update(1,1,n,l,r);
	}
	return 0;
}
2021/4/14 18:29
加载中...