MnZn线段树求调
查看原帖
MnZn线段树求调
664794
nie123楼主2022/9/30 08:13

code:

#include<stdio.h>
#define int long long
int p;//马蜂参考:皎月半洒花 
int a[100009];
int t[400009];
int g1[400009];//加法标记 
int g2[400009];//乘法标记 
inline int read(){//快读  
	int x=0;
	bool f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-') f=0;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return f?x:-x;
}
inline void write(int x){//快写 
	if(!x){
		putchar('0');
		return;
	}
	char F[20];
	if(x<0)
		putchar('-'),x=-x;
	int cnt=0;
	while(x)
		F[cnt++]=(x%10^48),x/=10;
	while(cnt)
		putchar(F[--cnt]);
	return;
}
inline int ls(int x){
	return x<<1;
}
inline int rs(int x){
	return x<<1|1;
}
inline void push_up(int x){
	t[x]=t[ls(x)]+t[rs(x)];
	t[x]%=p;
	return;
}	
inline void build(int x,int l,int r){
	if(l==r){
		t[x]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	push_up(x);
	return;
}	
inline void f(int x,int l,int r,int s1,int s2){
	t[x]=(t[x]*s2+s1*(r-l+1))%p;//更新值和标记 
	g2[x]=(g2[x]*s2)%p;//s1为加法更新值,s2为乘法 
	g1[x]=(g1[x]*s2+s1)%p;
	return;
}	
inline void push_down(int x,int l,int r){//下放标记 
	int mid=(l+r)>>1;
//	if(g1[x]!=0&&g2[x]!=1){
//		printf("nnd,gwwydsb");
//		return;
//	}
	f(ls(x),l,mid,g1[x],g2[x]);//更新子节点的值和标记 
	f(rs(x),mid+1,r,g1[x],g2[x]);
	g1[x]=0;//标记已经下放完了,直接清掉 
	g2[x]=1;//要加的数变为0,要乘的数变为1 
	return;
}
inline void update1(int x,int l,int r,int nl,int nr,int s){//区间加 
	if(nl<=l&&r<=nr){
		f(x,l,r,s,1);//一函数多用,这里直接默认子节点要乘的值为1 
		return;
	}
	int mid=(l+r)>>1;
	push_down(x,l,r);
	if(nl<=mid)
		update1(ls(x),l,mid,nl,nr,s);
	if(nr>mid)
		update1(rs(x),mid+1,r,nl,nr,s);
	push_up(x);
	return;
}
inline void update2(int x,int l,int r,int nl,int nr,int s){//区间乘 
	if(nl<=l&&r<=nr){
		f(x,l,r,0,s);//默认要加的数为0 
		return;
	}
	int mid=(l+r)>>1;
	push_down(x,l,r);
	if(nl<=mid)
		update2(ls(x),l,mid,nl,nr,s);
	if(nr>mid)
		update2(rs(x),mid+1,r,nl,nr,s);
	push_up(x);
	return;
}
inline int ask(int x,int l,int r,int nl,int nr){//询问 
	int ans=0;
	if(nl<=l&&r<=nr)
		return t[x];
	int mid=(l+r)>>1;
	push_down(x,l,r);
	if(nl<=mid)
		ans+=ask(ls(x),l,mid,nl,nr);
	if(nr>mid)
		ans+=ask(rs(x),mid+1,r,nl,nr);
//	push_up(x);
	return ans;
}
signed main(){
	//
	int n=read(),m=read();
	p=read();
	for(int i=1;i<=n;++i){
		a[i]=read();
	}
	build(1,1,n);
	while(m--){
		int op=read();
		int l=read();
		int r=read();
		if(op==1){
			int k=read();
			update2(1,1,n,l,r,k);
		}
		else if(op==2){
			int k=read();
			update1(1,1,n,l,r,k);
		}
		else{
			write(ask(1,1,n,l,r)%p);
			putchar('\n');
		}
	}
	return 0;
}

全WA

2022/9/30 08:13
加载中...