10分spaly求调
查看原帖
10分spaly求调
362627
frank15楼主2021/5/7 21:07
#include<iostream>
#include<cstdio>
#define mid ((l+r)>>1)
#define ls tree[x].ch[0]
#define rs tree[x].ch[1]
using namespace std;
const int maxn=4e6+5,inf=(1<<31)-1;
int n,m,pos,c,tot;
int a[maxn];
char op[20];
int tot2,rt;
struct t{
	int f,ch[2],sz;
	int val,lsum,rsum,sum,max_sum,tag;
	bool rev; 
}tree[maxn];
bool son(int x){
	return x==tree[tree[x].f].ch[1];
}
void maintain(int x){
	tree[x].sz=tree[ls].sz+tree[rs].sz+1;
	tree[x].sum=tree[ls].sum+tree[rs].sum+tree[x].val;
	tree[x].lsum=max(tree[ls].lsum,tree[ls].sum+tree[x].val+tree[rs].lsum);//ls.lsum>=0,?????sum?? 
	tree[x].rsum=max(tree[rs].rsum,tree[rs].sum+tree[x].val+tree[ls].rsum);
	tree[x].max_sum=tree[ls].rsum+tree[x].val+tree[rs].lsum;
	if(ls)
		tree[x].max_sum=max(tree[ls].max_sum,tree[x].max_sum);
	if(rs)
		tree[x].max_sum=max(tree[rs].max_sum,tree[x].max_sum);
	return ;
}
int build(int l,int r,int fa){
	if(l>r)
		return 0;
	int x=++tot2;
	tree[x].f=fa;
	tree[x].tag=inf;
	tree[x].val=a[mid];
	tree[x].ch[0]=build(l,mid-1,x);
	tree[x].ch[1]=build(mid+1,r,x);
	maintain(x);
	return x; 
}
void change(int x,int value){
	tree[x].tag=value;
	tree[x].val=value;
	tree[x].sum=value*tree[x].sz;
	if(value)
		tree[x].lsum=tree[x].rsum=tree[x].max_sum=tree[x].sum;
	else{
		tree[x].max_sum=value;
		tree[x].lsum=tree[x].rsum=0;
	}
}
void change2(int x){
	tree[x].rev^=1;
	swap(tree[x].lsum,tree[x].rsum);
	swap(ls,rs);
}
void push_down(int x){
	if(tree[x].tag!=inf){
		if(ls)
			change(ls,tree[x].tag);
		if(rs)
			change(rs,tree[x].tag);
		tree[x].tag=inf;
		tree[x].rev=0;
	}
	if(tree[x].rev){
		change2(ls);
		change2(rs);
		tree[x].rev=0;
	}
}
void rotate(int x){
	push_down(x);
	int y=tree[x].f,z=tree[y].f;
	bool chk=son(x),chk2=son(y);
	tree[y].ch[chk]=tree[x].ch[chk^1];
	if(tree[x].ch[chk^1])
		tree[tree[x].ch[chk^1]].f=y;
	tree[x].ch[chk^1]=y;
	tree[y].f=x;
	tree[x].f=z;
	if(z)
		tree[z].ch[chk2]=x;
	maintain(y);
	maintain(x);
	return ;
}
void splay(int x,int goal){
	while(tree[x].f!=goal){
		int y=tree[x].f;
		int z=tree[y].f;
		if(z!=goal){
			if(son(y)==son(z))
				rotate(y);
			else	
				rotate(x);
		}
		rotate(x);
	}
	if(!goal)
		rt=x;
}
int qfind(int k){
	int cur=rt;
	while(1){
	    push_down(cur);
		if(k<=tree[tree[cur].ch[0]].sz)
			cur=tree[cur].ch[0];
		else{
			k-=tree[tree[cur].ch[0]].sz+1;
			if(k<=0)
				return cur;
			cur=tree[cur].ch[1];
		}
	}
}
void qinsert(int l,int r,int k){
	int L=qfind(k),R=qfind(k+1);
	splay(L,0);
	splay(R,L);
	tree[R].ch[0]=build(l,r,R);
	maintain(R);
	maintain(L);
	return ;
}
void qdel(int k,int cnt){
	int L=qfind(k),R=qfind(k+cnt+1);
	splay(L,0);
	splay(R,L);
	tree[R].ch[0]=0;
	maintain(R);
	maintain(L);
	return ;
}
void same(int k,int cnt,int value){
	int L=qfind(k),R=qfind(k+cnt+1);
	splay(L,0);
	splay(R,L);
	change(tree[R].ch[0],value);
	maintain(R);
	maintain(L);
	return ;	
}
void rever(int k,int cnt){
	int L=qfind(k),R=qfind(k+cnt+1);
	splay(L,0);
	splay(R,L);
	int x=tree[R].ch[0];
	if(tree[x].tag==inf){ //==
		change2(x);
		maintain(R);
		maintain(L);
	}
}
void out(int k,int cnt){
	int L=qfind(k),R=qfind(k+cnt+1);
	splay(L,0);
	splay(R,L);
	printf("%d\n",tree[tree[R].ch[0]].sum);
	maintain(R);
	maintain(L);
}
void print(int x){
	cout<<x<<endl;
	printf("f:%d\n",tree[x].f);
	printf("ch[0]:%d\n",tree[x].ch[0]);
	printf("ch[1]:%d\n",tree[x].ch[1]);
	printf("lsum:%d\n",tree[x].lsum);
	printf("rsum:%d\n",tree[x].rsum);
	printf("sum:%d\n",tree[x].sum);
	printf("max_sum:%d\n",tree[x].max_sum);
	printf("sz:%d\n",tree[x].sz);
	printf("val:%d\n",tree[x].val);
	printf("tag:%d\n",tree[x].tag);
	printf("rev:%d\n",tree[x].rev);
	puts("");
}
void qput(int x){
	print(x);
	if(tree[x].ch[0])
		qput(tree[x].ch[0]);
	if(tree[x].ch[1])
		qput(tree[x].ch[1]);
}
int main(){
	scanf("%d%d",&n,&m);
	rt=build(1,2,0);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	qinsert(1,n,1);
	//qput(rt);
	while(m--){
		scanf("%s",op);
		if(op[0]=='I'){
			scanf("%d%d",&pos,&n);
			for(int i=1;i<=n;i++)
				scanf("%d",&a[i]);
			qinsert(1,n,pos+1);
		}
		if(op[0]=='D'){
			scanf("%d%d",&pos,&tot);
			qdel(pos,tot);
		}
		if(op[2]=='K'){
			scanf("%d%d%d",&pos,&tot,&c);
			same(pos,tot,c);
		}
		if(op[0]=='R'){
			scanf("%d%d",&pos,&tot);
			rever(pos,tot);
		}
		if(op[0]=='G'){
			scanf("%d%d",&pos,&tot);
			out(pos,tot);
		}
		if(op[2]=='X')
			printf("%d\n",tree[rt].max_sum);
	}
}
2021/5/7 21:07
加载中...