线段树求调,玄关
查看原帖
线段树求调,玄关
739840
zhiduanqinchang楼主2024/4/11 19:02
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll a,b,c,x,y,k,mod,m[500001<<2],p[500001<<2],j;
struct node{
	long long v,add,mul;
}t[500001<<2];
inline long long lt(long long i){
	return i<<1;
}
inline long long rt(long long i){
	return i<<1|1;
}
void gx(long long i){
	t[i].v=(t[lt(i)].v+t[rt(i)].v)%mod;
} 
void build(ll l,ll r,ll k){
	t[k].mul=1;
	t[k].add=0;
	if(l==r){
		t[k].v=m[l];
	}
	else{
		ll mid=(l+r)>>1;
		build(l,mid,lt(k));
		build(mid+1,r,rt(k));
		gx(k);	
	}
	t[k].v%=mod;
	return; 
}
void put(ll l,ll r,ll i){
	ll mid=(l+r)>>1;
	t[lt(i)].v=(t[lt(i)].v*t[i].mul+t[i].add*(mid-l+1))%mod;
	t[rt(i)].v=(t[rt(i)].v*t[i].mul+t[i].add*(r-mid))%mod;
	t[lt(i)].mul=(t[lt(i)].mul*t[i].mul)%mod;
	t[rt(i)].mul=(t[rt(i)].mul*t[i].mul)%mod;
	t[lt(i)].add=(t[lt(i)].add*t[i].mul+t[i].add)%mod;
	t[rt(i)].add=(t[rt(i)].add*t[i].mul+t[i].add)%mod;
	t[k].mul=1;
	t[k].add=0;
}
void update1(ll l,ll r,ll i,ll x,ll y,ll k){
	if(y<l||r<x){
		return;
	}
	if(x<=l&&y>=r){
		t[i].v=(t[i].v*k)%mod;
        t[i].mul=(t[i].mul*k)%mod;
        t[i].add=(t[i].add*k)%mod;
        return ;
	}
	put(l,r,i); 
	ll mid=(l+r)>>1;
	update1(l,mid,lt(i),x,y,k);
	update1(mid+1,r,rt(i),x,y,k);
	gx(i); 
	return ;
}
void update2(ll l,ll r,ll i,ll x,ll y,ll k){
	if(y<l||r<x){
		return;
	}
	if(x<=l&&y>=r){
		t[i].add=(t[i].add+k)%mod;
        t[i].v=(t[i].v+k*(r-l+1))%mod;
         return;
	}
	put(l,r,i);
	ll mid=(l+r)>>1;
	update2(l,mid,lt(i),x,y,k);
	update2(mid+1,r,rt(i),x,y,k);
	gx(i); 
	return ;
}
ll asd(ll l,ll r,ll i,ll x,ll y){
	if(y<l||r<x){
		return 0;
	}
	if(x<=l&&y>=r){
		return t[i].v;
	}
	put(l,r,i);
	ll mid=(l+r)>>1,sum=0;
	return (asd(l,mid,lt(i),x,y)+asd(mid+1,r,rt(i),x,y))%mod;
}
int main(){
	scanf("%lld %lld %lld",&a,&b,&mod);
	for(j=1;j<=a;j++)
		scanf("%lld",&m[j]);
		build(1,a,1);
	for(j=1;j<=b;j++){
		scanf("%lld",&c);
		if(c==1){
			scanf("%lld %lld %lld",&x,&y,&k);
			update1(1,a,1,x,y,k);
		}
		else if(c==2){
			scanf("%lld %lld %lld",&x,&y,&k);
			update2(1,a,1,x,y,k);
		}
		else if(c==3){
			scanf("%lld %lld",&x,&y);
			printf("%lld \n",asd(1,a,1,x,y));
		}}
		//system("pause");
	return 0;
} 
/*5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4
*/
2024/4/11 19:02
加载中...