我使用FHQ写了线段树2

虽然并没有任何的意义,但是我觉得很有意思,所以记录一下:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MN=1e6+116;
struct Node{
	int lc, rc, siz, rnd;
	int val, sum, addtag, multag;
}tr[MN];
int n, q, mod;
void pushup(int k){
	tr[k].siz=tr[tr[k].lc].siz+tr[tr[k].rc].siz+1;
	tr[k].sum=tr[tr[k].lc].sum+tr[tr[k].rc].sum+tr[k].val;
}
void pushdown(int k){
	if(tr[k].multag!=1){
		if(tr[k].lc){
			tr[tr[k].lc].val=(tr[tr[k].lc].val*tr[k].multag)%mod;
			tr[tr[k].lc].sum=(tr[tr[k].lc].sum*tr[k].multag)%mod;
			tr[tr[k].lc].addtag=(tr[tr[k].lc].addtag*tr[k].multag)%mod;
			tr[tr[k].lc].multag=(tr[tr[k].lc].multag*tr[k].multag)%mod;
		}
		if(tr[k].rc){
			tr[tr[k].rc].val=(tr[tr[k].rc].val*tr[k].multag)%mod;
			tr[tr[k].rc].sum=(tr[tr[k].rc].sum*tr[k].multag)%mod;
			tr[tr[k].rc].addtag=(tr[tr[k].rc].addtag*tr[k].multag)%mod;
			tr[tr[k].rc].multag=(tr[tr[k].rc].multag*tr[k].multag)%mod;			
		}
		tr[k].multag=1;
	}
	if(tr[k].addtag){
		if(tr[k].lc){
			tr[tr[k].lc].val=(tr[tr[k].lc].val+tr[k].addtag)%mod;
			tr[tr[k].lc].sum=(tr[tr[k].lc].sum+(tr[tr[k].lc].siz*tr[k].addtag)%mod)%mod;
			tr[tr[k].lc].addtag=(tr[tr[k].lc].addtag+tr[k].addtag)%mod;			
		}
		if(tr[k].rc){
			tr[tr[k].rc].val=(tr[tr[k].rc].val+tr[k].addtag)%mod;
			tr[tr[k].rc].sum=(tr[tr[k].rc].sum+(tr[tr[k].rc].siz*tr[k].addtag)%mod)%mod;	
			tr[tr[k].rc].addtag=(tr[tr[k].rc].addtag+tr[k].addtag)%mod;			
		}
		tr[k].addtag=0;
	}
	return;
}
void split(int k, int val, int &x, int &y){
	if(!k){x=0; y=0; return;}
	pushdown(k);
	if(tr[tr[k].lc].siz<val){
		x=k; val-=(tr[tr[k].lc].siz+1);
		split(tr[k].rc,val,tr[k].rc,y);
	}else{
		y=k; split(tr[k].lc,val,x,tr[k].lc);
	}
	pushup(k);
}
int merge(int x, int y){
	if(!x||!y) return x+y;
	if(tr[x].rnd<tr[y].rnd){
		pushdown(x);
		tr[x].rc=merge(tr[x].rc,y);
		pushup(x); return x;
	}else{
		pushdown(y);
		tr[y].lc=merge(x,tr[y].lc);
		pushup(y); return y;
	}
}
int root=0, tottt=0;
int Newnode(int val){
	++tottt;
	tr[tottt].siz=1;
	tr[tottt].rnd=rand();
	tr[tottt].multag=1;
	tr[tottt].sum=tr[tottt].val=val%mod;
	return tottt;
}
void insert(int val){
	root=merge(root,Newnode(val));
}
void Update_Add(int l, int r, int val){
	int x, y, z;
	split(root,r,x,y);
	split(x,l-1,x,z);
	tr[z].sum=(tr[z].sum+(tr[z].siz*val))%mod;
	tr[z].addtag=(tr[z].addtag+val)%mod;
	tr[z].val=(tr[z].val+val)%mod;
	pushdown(z);
	root=merge(merge(x,z),y);
	return;
}
void Update_Mul(int l, int r, int val){
	int x, y, z;
	split(root,r,x,y);
	split(x,l-1,x,z);
	tr[z].multag=(tr[z].multag*val)%mod;
	tr[z].val=(tr[z].val*val)%mod;
	tr[z].sum=(tr[z].sum*val)%mod;
	tr[z].addtag=(tr[z].addtag*val)%mod;
	pushdown(z);
	root=merge(merge(x,z),y);
	return;
}
int query(int l, int r){
	int x, y, z, res=0;
	split(root,r,x,y);
	split(x,l-1,x,z);
	res=tr[z].sum%mod;
	pushdown(z);
	root=merge(merge(x,z),y);
	return res;
}
void Solve(){
	cin>>n>>q>>mod;;
	for(int i=1; i<=n; ++i){
		int val; cin>>val;
		insert(val);
	}
	while(q--){
		int op, l, r, k;
		cin>>op>>l>>r;
		if(op==1){
			cin>>k;
			Update_Mul(l,r,k);
		}else if(op==2){
			cin>>k;
			Update_Add(l,r,k);
		}else{
			cout<<query(l,r)<<'\n';
		}
	}
}
signed main(){
	srand(time(0));
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	Solve();
	return 0;
}
posted @ 2025-10-29 17:09  BaiBaiShaFeng  阅读(2)  评论(0)    收藏  举报
Sakana Widget右下角定位