序列终结者

link

要求写一个数据结构,支持区间加,区间翻转,查询区间最大值。

没有动态插入和动态删除我不是很认可,还什么“序列终结者”,常用的都没有包含完。

就是板子。要注意的是一个点的最大值等于左右孩子的最大值和自己的data再取一次最大值(我也不知道当时脑子是怎么抽掉的)。另外就是pushup和pushnow要判断一下是不是对0号节点进行操作。对0号节点动刀子是大大的不可以的。其它就是pushup的时候要判左右孩子是不是0(或者把它maxn赋值成-maxn也可以)。由于脑子抽了很是调了一会。

code:

#include<bits/stdc++.h>
//#define zczc
const int N=50010;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline int max(int s1,int s2){
	return s1<s2?s2:s1;
}
inline void swap(int &s1,int &s2){
	int s3=s1;s1=s2;s2=s3;return;
}

int m,n;

#define lc t[x].ch[0]
#define rc t[x].ch[1]
struct node{
	int f,ch[2];
	int size,data,maxn;
	int add;bool lazy;
}t[N];
int root;
inline void pushup(int x){
	if(x==0)return;
	t[x].maxn=max(t[x].data,max(t[lc].maxn,t[rc].maxn));
	t[x].size=t[lc].size+t[rc].size+1;
}
inline void pushnow(int x,int add,bool lazy){
	if(x==0)return;
	if(lazy)t[x].lazy=t[x].lazy^1,swap(lc,rc);
	if(add)t[x].add+=add,t[x].data+=add,t[x].maxn+=add;
}
inline void pushdown(int x){
	pushnow(lc,t[x].add,t[x].lazy);
	pushnow(rc,t[x].add,t[x].lazy);
	t[x].add=t[x].lazy=0;
}
inline int build(int l,int r,int fa){
	if(l>r)return 0;
	int x=l+r+1>>1;
	t[x].size=1;t[x].f=fa;
	if(l==r)return l;
	lc=build(l,x-1,x);rc=build(x+1,r,x);
	pushup(x);return x;
}
inline int find(int x,int kk){
	pushdown(x);
	if(t[lc].size>=kk)return find(lc,kk);
	if(t[lc].size+1==kk)return x;
	return find(rc,kk-t[lc].size-1);
}
inline void rotate(int x){
	int y=t[x].f;int z=t[y].f;
	int kk=t[y].ch[1]==x;int cd=t[x].ch[kk^1];
	if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].f=z;
	t[cd].f=y;t[y].ch[kk]=cd;
	t[x].ch[kk^1]=y;t[y].f=x;
	pushup(y);pushup(x);
	if(y==root)root=x;return;
}
inline void splay(int x,int rt){
	while(t[x].f^rt){
		int y=t[x].f;int z=t[y].f;
		if(z^rt)(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
		rotate(x);
	}
	if(rt==0)root=x;
}
#undef lc
#undef rc

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);read(n);root=build(1,m+2,0);
	int op,l,r,data;t[0].maxn=-0x7fffffff;
	while(n--){
		read(op);read(l);read(r);l++;r++;
		int s1=find(root,l-1),s2=find(root,r+1);
		splay(s1,0);splay(s2,s1);
		int x=t[s2].ch[0];
		if(op==1){
			read(data);pushnow(x,data,false);
			pushup(s2);pushup(s1);
		}
		if(op==2){
			pushnow(x,0,true);
			pushup(s2);pushup(s1);
		}
		if(op==3)printf("%d\n",t[x].maxn);
	}
	
	return 0;
}
posted @ 2022-07-04 11:03  Feyn618  阅读(22)  评论(0编辑  收藏  举报