Luogu線段樹模板

線段樹1

支持:
1、區間修改
2、區間查詢

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#define lson (x<<1)
#define rson (x<<1|1)
using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> P;
priority_queue<P ,vector<P> ,greater<P> > q;
const int INF=0x7f7f7f;

struct SGT{
	int l,r;
	ll lazy;
	ll sum;
//	ll mn;
//	ll mx;
}t[4*100005];
ll a[100005],k;
int n,m,x,y,tag;

void push_up(int x){
	t[x].sum=t[lson].sum+t[rson].sum;
	//t[x].mn=min(t[lson].mn,t[rson].mn);
	//t[x].mx=max(t[lson].mx,t[rson].mx);
}

void push_down(int x){
	ll lazy=t[x].lazy;
	if(lazy){
		t[lson].lazy+=lazy;
		t[lson].sum+=lazy*(t[lson].r-t[lson].l+1);
//		t[lson].mn+=lazy;
//		t[lson].mx+=lazy;
		t[rson].lazy+=lazy;
		t[rson].sum+=lazy*(t[rson].r-t[rson].l+1);
//		t[rson].mn+=lazy;
//		t[rson].mx+=lazy;
	}
	t[x].lazy=0;
}

void Build(int x,int l,int r){
	t[x].l=l;t[x].r=r;
	t[x].lazy=0;
	t[x].sum=0;
//	t[x].mn=0;
//	t[x].mx=0;
	if(t[x].l==t[x].r){
		t[x].sum=a[t[x].l];
//		t[x].mn=a[t[x].l];
//		t[x].mx=a[t[x].l];
		return;
	}
	int mid=(t[x].l+t[x].r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
	push_up(x);
}

void Interval_modify(int x,int l,int r,ll val){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].lazy+=val;
		t[x].sum+=(t[x].r-t[x].l+1)*val;
//		t[x].mn+=val;
//		t[x].mx+=val;
		return;
	}
	else{
		int mid=(t[x].l+t[x].r)>>1;
		push_down(x);
		if(l<=mid) Interval_modify(lson,l,r,val);
		if(r>mid) Interval_modify(rson,l,r,val);
		push_up(x);
	}
}

ll Interval_query(int x,int l,int r){
	if(t[x].l>=l&&t[x].r<=r){
		return t[x].sum;
//		return t[x].mn;
//		return t[x].mx;
	}
	else{
		int mid=(t[x].l+t[x].r)>>1;
		push_down(x);
		ll res=0;
//		ll res=INF;
//		ll res=-1;
		if(l<=mid){
			res+=Interval_query(lson,l,r);
//			res=min(res,Interval_query(lson,l,mid));
//			res=max(res,Interval_query(lson,l,mid));
		}
		if(r>mid){
			res+=Interval_query(rson,l,r);
//			res=min(res,Interval_query(rson,mid+1,r));
//			res=max(res,Interval_query(rson,mid+1,r));
		}
		return res;
	}
}

int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	case1:Interval add k
//	case2:Interval query sum
	cin >> n >> m;
	for(int i=1;i<=n;i++)
		cin >> a[i];
	Build(1,1,n);
	//cout << t[1].sum << endl;
	for(int i=1;i<=m;i++){
		cin >> tag;
		if(tag==1){
			cin >> x >> y >> k;
			Interval_modify(1,x,y,k);
		}
		if(tag==2){
			cin >> x >> y;
			cout << Interval_query(1,x,y) << endl;
		}
	}
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}

線段樹2

支持:
1、區間加法
2、區間乘法
3、區間查詢


```cpp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#define lson (x<<1)
#define rson (x<<1|1)
using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> P;
priority_queue<P ,vector<P> ,greater<P> > q;
const int INF=0x7f7f7f;

struct SGT{
	int l,r;
	ll add_lazy;
	ll mul_lazy;
	ll sum;
//	ll mn;
//	ll mx;
}t[4*100005];
ll a[100005],k,mod;
int n,m,x,y,tag;

void push_up(int x){
	t[x].sum=(t[lson].sum+t[rson].sum)%mod;
	//t[x].mn=min(t[lson].mn,t[rson].mn);
	//t[x].mx=max(t[lson].mx,t[rson].mx);
}

void push_down(int x){
	t[lson].sum=(t[lson].sum*t[x].mul_lazy+t[x].add_lazy*(t[lson].r-t[lson].l+1))%mod;
	t[lson].add_lazy=(t[lson].add_lazy*t[x].mul_lazy+t[x].add_lazy)%mod;
	t[lson].mul_lazy=(t[lson].mul_lazy*t[x].mul_lazy)%mod;
//	t[lson].mn=(t[lson].mn*t[x].mul_lazy+t[x].add_lazy)%mod;
//	t[lson].mx=(t[lson].mx*t[x].mul_lazy+t[x].add_lazy)%mod;
	t[rson].sum=(t[rson].sum*t[x].mul_lazy+t[x].add_lazy*(t[rson].r-t[rson].l+1))%mod;
	t[rson].add_lazy=(t[rson].add_lazy*t[x].mul_lazy+t[x].add_lazy)%mod;
	t[rson].mul_lazy=(t[rson].mul_lazy*t[x].mul_lazy)%mod;
//	t[rson].mn=(t[rson].mn*t[x].mul_lazy+t[x].add_lazy)%mod;
//	t[rson].mn=(t[rson].mn*t[x].mul_lazy+t[x].add_lazy)%mod;
	t[x].add_lazy=0;
	t[x].mul_lazy=1;
}

void Build(int x,int l,int r){
	t[x].l=l;t[x].r=r;
	t[x].add_lazy=0;
	t[x].mul_lazy=1;
	t[x].sum=0;
//	t[x].mn=0;
//	t[x].mx=0;
	if(t[x].l==t[x].r){
		t[x].sum=a[t[x].l]%mod;
//		t[x].mn=a[t[x].l]%mod;
//		t[x].mx=a[t[x].l]%mod;
		return;
	}
	int mid=(t[x].l+t[x].r)>>1;
	Build(lson,l,mid);
	Build(rson,mid+1,r);
	push_up(x);
}

void Interval_modify_mul(int x,int l,int r,ll val){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].mul_lazy=(t[x].mul_lazy*val)%mod;
		t[x].add_lazy=(t[x].add_lazy*val)%mod;
		t[x].sum=(t[x].sum*val)%mod;
//		t[x].mn=(t[x].mn*val)%mod;
//		t[x].mx=(t[x].mx*val)%mod;
		return;
	}
	else{
		int mid=(t[x].l+t[x].r)>>1;
		push_down(x);
		if(l<=mid) Interval_modify_mul(lson,l,r,val);
		if(r>mid) Interval_modify_mul(rson,l,r,val);
		push_up(x);
	}
}

void Interval_modify_add(int x,int l,int r,ll val){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].add_lazy=(t[x].add_lazy+val)%mod;
		t[x].sum=(t[x].sum+(t[x].r-t[x].l+1)*val)%mod;
//		t[x].mn=(t[x].mn*val)%mod;
//		t[x].mx=(t[x].mx*val)%mod;
		return;
	}
	else{
		int mid=(t[x].l+t[x].r)>>1;
		push_down(x);
		if(l<=mid) Interval_modify_add(lson,l,r,val);
		if(r>mid) Interval_modify_add(rson,l,r,val);
		push_up(x);
	}
}

ll Interval_query(int x,int l,int r){
	if(t[x].l>=l&&t[x].r<=r){
		return t[x].sum%=mod;
//		return t[x].mn%=mod;
//		return t[x].mx%=mod;
	}
	else{
		int mid=(t[x].l+t[x].r)>>1;
		push_down(x);
		ll res=0;
//		ll res=INF;
//		ll res=-1;
		if(l<=mid){
			res+=Interval_query(lson,l,r);
//			res=min(res,Interval_query(lson,l,mid));
//			res=max(res,Interval_query(lson,l,mid));
			res%=mod;
		}
		if(r>mid){
			res+=Interval_query(rson,l,r);
//			res=min(res,Interval_query(rson,mid+1,r));
//			res=max(res,Interval_query(rson,mid+1,r));
			res%=mod;
		}
		return res;
	}
}

int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	case1:Interval multiply k
//	case2:Interval add k
//	case3:Interval query sum mod p
	cin >> n >> m >> mod;
	for(int i=1;i<=n;i++)
		cin >> a[i];
	Build(1,1,n);
	//cout << t[1].sum << endl;
	for(int i=1;i<=m;i++){
		cin >> tag;
		if(tag==1){
			cin >> x >> y >> k;
			Interval_modify_mul(1,x,y,k);
		}
		if(tag==2){
			cin >> x >> y >> k;
			Interval_modify_add(1,x,y,k);
		}
		if(tag==3){
			cin >> x >> y;
			cout << Interval_query(1,x,y) << endl;
		}
	}
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章