为什么用平衡树做线段树板子会T啊
查看原帖
为什么用平衡树做线段树板子会T啊
1420231
yy0707楼主2024/11/28 14:56
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,m,t,x,y,k;
template<typename T>
struct sequence{
	private:
		mt19937 random;
		struct node{
			T v,sum,tag1,tag2;int s,p;node*l,*r;
			void update(){
				sum=v,s=1;
				if(l)sum=(sum+l->sum)%m,s+=l->s;
				if(r)sum=(sum+r->sum)%m,s+=r->s;
			}void push(){
				if(l)l->v=(l->v*tag1+tag2)%m,l->tag1=(l->tag1*tag1)%m,l->tag2=(l->tag2*tag1+tag2)%m,l->sum=(l->sum*tag1+l->s*tag2)%m;
				if(r)r->v=(r->v*tag1+tag2)%m,r->tag1=(r->tag1*tag1)%m,r->tag2=(r->tag2*tag1+tag2)%m,r->sum=(r->sum*tag1+r->s*tag2)%m;
				tag1=1,tag2=0,update();
			}
		}*root;
		node*newnode(T v){
			node*p=new node;p->v=v,p->sum=v,
			p->tag1=1,p->tag2=0,p->p=random(),
			p->s=1,p->l=p->r=0;return p;
		}void split(node*p,int k,node*&l,node*&r){
			if(!p)return void(l=r=0);
			p->push();int s=p->l?p->l->s:0;
			if(s+1<=k)split(p->r,k-s-1,p->r,r),l=p;
			else split(p->l,k,l,p->l),r=p;
			p->update();
		}node*merge(node*l,node*r){
			if(!l||!r)return l?l:r;
			l->push(),r->push();
			if(l->p>r->p)return l->r=merge(l->r,r),l->update(),l;
			return r->l=merge(l,r->l),r->update(),r;
		}
	public:
		sequence():root(0),random(time(0)){}
		void insert(int k,T v){
			node*x,*y;split(root,k,x,y),
			root=merge(merge(x,newnode(v)),y);
		}void mul(int l,int r,T v){
			node*x,*y,*z;split(root,r,y,z),
			split(y,l-1,x,y),y->tag1=(y->tag1*v)%m,y->v=(y->v*v)%m;
			root=merge(merge(x,y),z);
		}void add(int l,int r,T v){
			node*x,*y,*z;split(root,r,y,z),
			split(y,l-1,x,y),y->tag2=(y->tag2+v)%m,y->v=(y->v+v)%m;
			root=merge(merge(x,y),z);
		}T prod(int l,int r){
			node*x,*y,*z;split(root,r,y,z),
			split(y,l-1,x,y);T res=y?y->sum:0;
			root=merge(merge(x,y),z);return res;
		}
};sequence<int>a;
signed main(){
	cin>>n>>q>>m;
	for(int i=1;i<=n;i++)cin>>t,a.insert(i,t);
	while(q--){
		cin>>t>>x>>y;
		if(t==1)cin>>k,a.mul(x,y,k);
		else if(t==2)cin>>k,a.add(x,y,k);
		else cout<<a.prod(x,y)<<'\n';
	}
}
2024/11/28 14:56
加载中...