线段树(悲)

这两天在练线段树,写了几个模板

P3372 【模板】线段树 1

#include<bits/stdc++.h> 
#define int long long
using namespace std;
const int maxx=1e5+5;
int mod,a[maxx],n,q;
struct node{int v,lazy1,lazy2;}tree[maxx<<2];
void build(int x,int l,int r)
{
	if(l==r) {tree[x].v=a[l];return;}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);build((x<<1)+1,mid+1,r);
	tree[x].v=tree[x<<1].v+tree[(x<<1)+1].v;
	return;
}
void push_down(int x,int l, int r)
{
	int t=tree[x].lazy1;int mid=(l+r)>>1;
	tree[x<<1].v+=t*(mid-l+1);
	tree[(x<<1)+1].v+=t*(r-mid);
	tree[x<<1].lazy1+=t;
	tree[(x<<1)+1].lazy1+=t;
	tree[x].lazy1=0;
}
void add(int x,int l,int r,int ll,int rr,int k)
{
	if(ll<=l&&r<=rr) {tree[x].v+=k*(r-l+1);tree[x].lazy1+=k;return;}
	int mid=(l+r)>>1;push_down(x,l,r);
	if(ll<=mid) add(x<<1,l,mid,ll,rr,k);
	if(mid+1<=rr) add((x<<1)+1,mid+1,r,ll,rr,k);
	tree[x].v=tree[x<<1].v+tree[(x<<1)+1].v;
	return;
}
int ask(int x,int l,int r,int ll,int rr)
{
	int ans=0;
	if(ll<=l&&r<=rr) {return tree[x].v;}
	int mid=(l+r)>>1;push_down(x,l,r);
	if(ll<=mid) ans+=ask(x<<1,l,mid,ll,rr);
	if(mid+1<=rr) ans+=ask((x<<1)+1,mid+1,r,ll,rr);
	return ans;
}
signed main()
{
	cin>>n>>q;int tmp=0,x=0,y=0,k=0;
	for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);
	for(int i=1;i<=q;i++)
	{
		cin>>tmp;
		if(tmp==1) {cin>>x>>y>>k;add(1,1,n,x,y,k);}
		else {cin>>x>>y;cout<<ask(1,1,n,x,y)<<endl;}
	}
	return 0;
}

P3372 【模板】线段树 2

#include<bits/stdc++.h> 
#define int long long
using namespace std;
const int maxx=1e5+5;
int mod,a[maxx],n,q;
struct node{int v=0,lazy1=0,lazy2=1;}tree[maxx<<2];
void build(int x,int l,int r)
{
	if(l==r) {tree[x].v=a[l];return;}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);build((x<<1)+1,mid+1,r);
	tree[x].v=tree[x<<1].v+tree[(x<<1)+1].v;
	tree[x].v%=mod;
	return;
}
void push_down(int x,int l, int r)
{
	int t1=tree[x].lazy1;int t2=tree[x].lazy2;int mid=(l+r)>>1;
	tree[x<<1].v*=t2;tree[(x<<1)+1].v*=t2;
	tree[x<<1].lazy1*=t2;tree[(x<<1)+1].lazy1*=t2;
	tree[x<<1].lazy2*=t2;tree[(x<<1)+1].lazy2*=t2;
	tree[x<<1].v+=t1*(mid-l+1);tree[(x<<1)+1].v+=t1*(r-mid);
	tree[x<<1].lazy1+=t1;tree[(x<<1)+1].lazy1+=t1;
	tree[x<<1].v%=mod;tree[(x<<1)+1].v%=mod;
	tree[x<<1].lazy1%=mod;tree[(x<<1)+1].lazy1%=mod;
	tree[x<<1].lazy2%=mod;tree[(x<<1)+1].lazy2%=mod;
	tree[x].lazy1=0;tree[x].lazy2=1;return;
}
void add(int x,int l,int r,int ll,int rr,int k)
{
	if(ll<=l&&r<=rr)
	{
		tree[x].v+=k*(r-l+1);tree[x].lazy1+=k;
		tree[x].lazy1%=mod;return;
	}
	int mid=(l+r)>>1;push_down(x,l,r);
	if(ll<=mid) add(x<<1,l,mid,ll,rr,k);
	if(mid+1<=rr) add((x<<1)+1,mid+1,r,ll,rr,k);
	tree[x].v=tree[x<<1].v+tree[(x<<1)+1].v;
	tree[x].v%=mod;
	return;
}
void mul(int x,int l,int r,int ll,int rr,int k)
{
	if(ll<=l&&r<=rr)
	{
		tree[x].v*=k;tree[x].lazy1*=k;tree[x].lazy2*=k;
		tree[x].lazy1%=mod;tree[x].lazy2%=mod;return;
	}
	int mid=(l+r)>>1;push_down(x,l,r);
	if(ll<=mid) mul(x<<1,l,mid,ll,rr,k);
	if(mid+1<=rr) mul((x<<1)+1,mid+1,r,ll,rr,k);
	tree[x].v=tree[x<<1].v+tree[(x<<1)+1].v;
	tree[x].v%=mod;
	return;
}
int ask(int x,int l,int r,int ll,int rr)
{
	int ans=0;
	if(ll<=l&&r<=rr) {return tree[x].v;}
	int mid=(l+r)>>1;push_down(x,l,r);
	if(ll<=mid) ans+=ask(x<<1,l,mid,ll,rr);
	if(mid+1<=rr) ans+=ask((x<<1)+1,mid+1,r,ll,rr);
	return ans;
}
signed main()
{
	cin>>n>>q>>mod;int tmp=0,x=0,y=0,k=0;
	for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);
	for(int i=1;i<=q;i++)
	{
		cin>>tmp;
		if(tmp==1) {cin>>x>>y>>k;mul(1,1,n,x,y,k);}
		if(tmp==2) {cin>>x>>y>>k;add(1,1,n,x,y,k);}
		if(tmp==3) {cin>>x>>y;cout<<ask(1,1,n,x,y)%mod<<endl;}
	}
	return 0;
}

P6242 【模板】线段树 3(区间最值操作、区间历史最值)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxx=5e5+5;const int minn=-5e9;
struct node{
int l,r,sum,maxn,cnt,se,hismax;
int mxtag,ottag,hismxtg,hisottg;
}tree[maxx<<2];
int n,m,a[maxx];
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||'9'<ch) {if(ch=='-') f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline void change(int x,int add1,int add2,int add3,int add4){
	tree[x].sum+=(add1*tree[x].cnt+add2*(tree[x].r-tree[x].l+1-tree[x].cnt));
	tree[x].hismax=max(tree[x].hismax,tree[x].maxn+add3);
	//必须先更新历史最大值 
	tree[x].maxn+=add1;if(tree[x].se!=minn) tree[x].se+=add2;
	tree[x].hismxtg=max(tree[x].hismxtg,tree[x].mxtag+add3);
	tree[x].hisottg=max(tree[x].hisottg,tree[x].ottag+add4);
	tree[x].mxtag+=add1;tree[x].ottag+=add2;return;
}
inline void push_down(int x){
	int ls=x<<1,rs=(x<<1)+1;
	int tmp=max(tree[ls].maxn,tree[rs].maxn);
	if(tree[ls].maxn==tmp)
	change(ls,tree[x].mxtag,tree[x].ottag,tree[x].hismxtg,tree[x].hisottg);
	else change(ls,tree[x].ottag,tree[x].ottag,tree[x].hisottg,tree[x].hisottg);
	if(tree[rs].maxn==tmp)
	change(rs,tree[x].mxtag,tree[x].ottag,tree[x].hismxtg,tree[x].hisottg);
	else change(rs,tree[x].ottag,tree[x].ottag,tree[x].hisottg,tree[x].hisottg);
	tree[x].mxtag=tree[x].ottag=tree[x].hismxtg=tree[x].hisottg=0;
	return;
}
inline void push_up(int x){
	int ls=x<<1,rs=(x<<1)+1;
	tree[x].sum=tree[ls].sum+tree[rs].sum;
	tree[x].hismax=max(tree[ls].hismax,tree[rs].hismax);
	int tmp=max(tree[ls].maxn,tree[rs].maxn);
	tree[x].maxn=tmp;
	if(tree[ls].maxn==tree[rs].maxn){
		tree[x].cnt=tree[ls].cnt+tree[rs].cnt;
		tree[x].se=max(tree[ls].se,tree[rs].se);
	}
	else{
		if(tree[ls].maxn==tmp){
			tree[x].cnt=tree[ls].cnt;
			tree[x].se=max(tree[ls].se,tree[rs].maxn);
		}
		else{
			tree[x].cnt=tree[rs].cnt;
			tree[x].se=max(tree[ls].maxn,tree[rs].se);
		}
	}
	return;
}
inline void build(int x,int ll,int rr){
	tree[x].l=ll,tree[x].r=rr;
	if(ll==rr){
		tree[x].sum=a[ll];tree[x].maxn=a[ll];
		tree[x].cnt=1;tree[x].se=minn;tree[x].hismax=a[ll];
	}
	else{
		int mid=(ll+rr)>>1;
		build(x<<1,ll,mid);build((x<<1)+1,mid+1,rr);
		push_up(x);
	}
	return;
}
inline void add(int x,int ll,int rr,int k){
	if(rr<tree[x].l||tree[x].r<ll) return;
	if(ll<=tree[x].l&&tree[x].r<=rr){
		tree[x].sum+=k*(tree[x].r-tree[x].l+1);
		tree[x].maxn+=k;tree[x].mxtag+=k;tree[x].ottag+=k;
		if(tree[x].se!=minn) tree[x].se+=k;
		tree[x].hismax=max(tree[x].hismax,tree[x].maxn);
		tree[x].hismxtg=max(tree[x].hismxtg,tree[x].mxtag);
		tree[x].hisottg=max(tree[x].hisottg,tree[x].ottag);
		return;//注意写return!!! 
	}
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1;
	if(ll<=mid) add(x<<1,ll,rr,k);
	if(rr>=mid+1) add((x<<1)+1,ll,rr,k);
	push_up(x);return;
}
inline void qmin(int x,int ll,int rr,int v){
	if(rr<tree[x].l||tree[x].r<ll||tree[x].maxn<=v) return;
	if(ll<=tree[x].l&&tree[x].r<=rr&&tree[x].se<v){
	//为保证se为严格次大值,此处tree[x].se<v必须使用< 
		int k=tree[x].maxn-v;
		tree[x].sum-=tree[x].cnt*k;
		tree[x].maxn=v;tree[x].mxtag-=k;
		return;
	}
	push_down(x);
	qmin(x<<1,ll,rr,v);qmin((x<<1)+1,ll,rr,v);
	push_up(x);return;
}
inline int asksum(int x,int ll,int rr){
	if(rr<tree[x].l||tree[x].r<ll) return 0;
	if(ll<=tree[x].l&&tree[x].r<=rr) return tree[x].sum;
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1,ans=0;
	if(ll<=mid) ans+=asksum(x<<1,ll,rr);
	if(rr>=mid+1) ans+=asksum((x<<1)+1,ll,rr);
	return ans;
}
inline int amax(int x,int ll,int rr){
	if(rr<tree[x].l||tree[x].r<ll) return minn;
	if(ll<=tree[x].l&&tree[x].r<=rr) return tree[x].maxn;
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1,ans=minn;
	if(ll<=mid) ans=max(ans,amax(x<<1,ll,rr));
	if(rr>=mid+1) ans=max(ans,amax((x<<1)+1,ll,rr));
	return ans;
}
inline int bmax(int x,int ll,int rr){
	if(rr<tree[x].l||tree[x].r<ll) return minn;
	if(ll<=tree[x].l&&tree[x].r<=rr) return tree[x].hismax;
	push_down(x);
	int mid=(tree[x].l+tree[x].r)>>1,ans=minn;
	if(ll<=mid) ans=max(ans,bmax(x<<1,ll,rr));
	if(rr>=mid+1) ans=max(ans,bmax((x<<1)+1,ll,rr));
	return ans;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);int tx=0,lx=0,rx=0,kx=0;
	for(int i=1;i<=m;i++){
		cin>>tx>>lx>>rx;
		if(tx==1) {cin>>kx;add(1,lx,rx,kx);}
		if(tx==2) {cin>>kx;qmin(1,lx,rx,kx);}
		if(tx==3) cout<<asksum(1,lx,rx)<<endl;
		if(tx==4) cout<<amax(1,lx,rx)<<endl;
		if(tx==5) cout<<bmax(1,lx,rx)<<endl;
	}
	return 0;
}

(这题一遍过)

P4314 CPU 监控

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxx=1e5+5;const int im=-(1e11);
struct node{
	int l,r,maxn,hismax;
	int cover,add,hisadd,hiscad;
}tree[maxx<<2];
int m,n;int a[maxx];
inline void push_up(int x){
	int ls=x<<1,rs=(x<<1)+1;
	tree[x].maxn=max(tree[ls].maxn,tree[rs].maxn);
	tree[x].hismax=max(tree[ls].hismax,tree[rs].hismax);
	return;
}
inline void upadd(int x,int add1,int add2){
	tree[x].hismax=max(tree[x].hismax,tree[x].maxn+add2);
	tree[x].maxn+=add1;
	tree[x].hisadd=max(tree[x].hisadd,tree[x].add+add2);
	tree[x].add+=add1;
	return;
}
inline void change(int x,int cov1,int cov2){
	tree[x].hismax=max(tree[x].hismax,cov2);
	tree[x].maxn=cov1;
	tree[x].hiscad=max(tree[x].hiscad,cov2);
	tree[x].cover=cov1;
	return;
}
inline void push_down(int x){
	int ls=x<<1,rs=(x<<1)+1;
	if(tree[ls].cover==im) upadd(ls,tree[x].add,tree[x].hisadd);
	else change(ls,tree[x].add+tree[ls].maxn,tree[x].hisadd+tree[ls].maxn);
	if(tree[rs].cover==im) upadd(rs,tree[x].add,tree[x].hisadd);
	else change(rs,tree[x].add+tree[rs].maxn,tree[x].hisadd+tree[rs].maxn);
	if(tree[x].cover!=im){
	change(ls,tree[x].cover,tree[x].hiscad);
	change(rs,tree[x].cover,tree[x].hiscad);
	}
	tree[x].add=tree[x].hisadd=0;tree[x].cover=tree[x].hiscad=im;
	return;
}
inline void build(int x,int ll,int rr){
	tree[x].l=ll;tree[x].r=rr;tree[x].cover=tree[x].hiscad=im;
	tree[x].hismax=im;
	if(ll==rr) {tree[x].maxn=tree[x].hismax=a[ll];return;}
	int mid=(ll+rr)>>1;
	build(x<<1,ll,mid);build((x<<1)+1,mid+1,rr);
	push_up(x);return;
}
inline void cvr(int x,int ll,int rr,int k){
	if(rr<tree[x].l||tree[x].r<ll) return;
	if(ll<=tree[x].l&&tree[x].r<=rr){
		tree[x].hismax=max(tree[x].hismax,k);
		tree[x].hiscad=max(tree[x].hiscad,k);
		tree[x].maxn=k;tree[x].cover=k;
		return;
	}
	push_down(x);
	cvr(x<<1,ll,rr,k);cvr((x<<1)+1,ll,rr,k);
	push_up(x);return;
}
inline void pluss(int x,int ll,int rr,int k){
	if(rr<tree[x].l||tree[x].r<ll) return;
	if(ll<=tree[x].l&&tree[x].r<=rr){
		if(tree[x].cover!=im) cvr(x,ll,rr,tree[x].cover+k);
		else{
			tree[x].hismax=max(tree[x].hismax,tree[x].maxn+k);
			tree[x].hisadd=max(tree[x].hisadd,tree[x].add+k);
			tree[x].maxn+=k;tree[x].add+=k;
		}return;
	}
	push_down(x);
	pluss(x<<1,ll,rr,k);pluss((x<<1)+1,ll,rr,k);
	push_up(x);return;
}
inline int askmax(int x,int ll,int rr){
	if(rr<tree[x].l||tree[x].r<ll) return im;
	if(ll<=tree[x].l&&tree[x].r<=rr) return tree[x].maxn;
	push_down(x);
	return max(askmax(x<<1,ll,rr),askmax((x<<1)+1,ll,rr));
}
inline int askhis(int x,int ll,int rr){
	if(rr<tree[x].l||tree[x].r<ll) return im;
	if(ll<=tree[x].l&&tree[x].r<=rr) return tree[x].hismax;
	push_down(x);
	return max(askhis(x<<1,ll,rr),askhis((x<<1)+1,ll,rr));
}
signed main(){
	cin>>n;for(int i=1;i<=n;i++) cin>>a[i];cin>>m;
	build(1,1,n);
	int tx,ty,tz;char t;
	for(int i=1;i<=m;i++){
		/*for(int j=1;j<=26;j++){
		cout<<"l,r:"<<tree[j].l<<" "<<tree[j].r<<" ";
		cout<<tree[j].maxn<<" "<<tree[j].hismax<<" ";
		cout<<tree[j].add<<" "<<tree[j].hisadd<<" ";
		cout<<tree[j].cover<<" "<<tree[j].hiscad<<" ";
		cout<<endl;
	}*/
		cin>>t>>tx>>ty;
		if(t=='Q') cout<<askmax(1,tx,ty)<<endl;
		if(t=='A') cout<<askhis(1,tx,ty)<<endl;
		if(t=='P') {cin>>tz;pluss(1,tx,ty,tz);}
		if(t=='C') {cin>>tz;cvr(1,tx,ty,tz);}
	}/*
	for(int j=1;j<=26;j++){
		cout<<"l,r:"<<tree[j].l<<" "<<tree[j].r<<" ";
		cout<<tree[j].maxn<<" "<<tree[j].hismax<<" ";
		cout<<tree[j].add<<" "<<tree[j].hisadd<<" ";
		cout<<tree[j].cover<<" "<<tree[j].hiscad<<" ";
		cout<<endl;
	}*/
	return 0;
}

(这题调了一天orz)

posted @   Gcint  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示