[NOI2005]维护序列 样例过不了 FHQ Treap
  • 板块学术版
  • 楼主xcyyyyyy
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/1/12 18:29
  • 上次更新2023/10/24 04:33:28
查看原帖
[NOI2005]维护序列 样例过不了 FHQ Treap
691447
xcyyyyyy楼主2023/1/12 18:29
#include<ctime>
#include<cstdio>
#include<random>
#include<algorithm>
#define SIZE 500005
typedef long long ll;
using namespace std;
struct Node{
	int l,r,maxn,pre;
	Node operator + (const Node &that)const{
		if(pre==0x3f3f3f3f)return that;
		if(that.pre==0x3f3f3f3f)return (*this);
		Node iwi;
		iwi.l=max(l,pre+that.l);
		iwi.r=max(that.r,that.pre+r);
		iwi.maxn=max(max(maxn,that.maxn),r+that.l);
		iwi.pre=pre+that.pre;
		return iwi;
	}
	Node(){pre=0x3f3f3f3f;}
};
int root,tot;
Node lhz[SIZE];
char op[10];
int key[SIZE],size[SIZE],lazy[SIZE],tad[SIZE],value[SIZE],lc[SIZE],rc[SIZE];
int tack[SIZE],change[SIZE],top;
inline int Newnode(int k){
	int p;
	if(top)p=tack[top--];
	else p=++tot;
	size[p]=1;
	lazy[p]=0;
	tad[p]=0x3f3f3f3f;
	lc[p]=rc[p]=0;
	value[p]=rand();
	key[p]=lhz[p].l=lhz[p].maxn=lhz[p].r=lhz[p].pre=k;
	return p;
}
inline int Get_size(int p){
	return p?size[p]:0;
}
inline void push_down(int p){
	if(lazy[p]){
		lazy[p]=0;
		if(lc[p]){
			lazy[lc[p]]^=1;
			swap(lc[lc[p]],rc[lc[p]]);
			swap(lhz[lc[p]].l,lhz[lc[p]].r);
		}
		if(rc[p]){
			lazy[rc[p]]^=1;
			swap(lc[rc[p]],rc[rc[p]]);
			swap(lhz[rc[p]].l,lhz[rc[p]].r);
		}
	}
	if(tad[p]!=0x3f3f3f3f){
		if(lc[p]){
			if(tad[p]<0){
				lhz[lc[p]].l=lhz[lc[p]].r=lhz[lc[p]].maxn=tad[p];
				lhz[lc[p]].pre=tad[p]*size[lc[p]];
			}
			else{
				lhz[lc[p]].l=lhz[lc[p]].r=lhz[lc[p]].maxn=lhz[lc[p]].pre=tad[p]*size[lc[p]];
			}
		}
		if(rc[p]){
			if(tad[p]<0){
				lhz[rc[p]].l=lhz[rc[p]].r=lhz[rc[p]].maxn=tad[p];
				lhz[rc[p]].pre=tad[p]*size[rc[p]];
			}
			else{
				lhz[rc[p]].l=lhz[rc[p]].r=lhz[rc[p]].maxn=lhz[rc[p]].pre=tad[p]*size[rc[p]];
			}
		}
		tad[p]=0x3f3f3f3f;
	}
}
inline void push_up(int p){
	Node now;
	now.l=now.r=now.maxn=now.pre=key[p];
	lhz[p]=lhz[lc[p]]+now+lhz[rc[p]];
	size[p]=size[lc[p]]+size[rc[p]]+1;
}
void Split(int root,int siz,int &p,int &q){
	if(!root){
		p=q=0;
		return;
	}
	push_down(root);
	if(size[lc[root]]<siz){
		p=root;
		Split(rc[p],siz-size[lc[p]]-1,rc[p],q);
		push_up(p);
	}
	else{
		q=root;
		Split(lc[q],siz,p,lc[q]);
		push_up(q);
	}
}
int Merge(int p,int q){
	if(!p||!q)return p|q;
	if(value[p]>value[q]){
		push_down(p);
		rc[p]=Merge(rc[p],q);
		push_up(p);
		return p;
	}
	else{
		push_down(q);
		lc[q]=Merge(p,lc[q]);
		push_up(q);
		return q;
	}
}
int build(int l,int r){
	if(l==r)return Newnode(change[l]);
	int m=(l+r)>>1;
	return Merge(build(l,m),build(m+1,r));
}
void Delete(int p){
	if(!p)return;
	tack[++top]=p;
	Delete(lc[p]);
	Delete(rc[p]);
}
void insert(int p,int tot){
	int x,y,z;
	int l=p,r=p+tot-1;
	Split(root,l-1,x,y);
	Split(y,r-l+1,y,z);
	root=Merge(Merge(x,build(1,tot)),y);
}
void erase(int p,int tot){
	int x,y,z;
	int l=p,r=p+tot-1;
	Split(root,l-1,x,y);
	Split(root,r-l+1,y,z);
	Delete(y);
	root=Merge(x,z);
}
void update(int p,int tot,int v){
	int x,y,z;
	int l=p,r=p+tot-1;
	Split(root,l-1,x,y);
	Split(root,r-l+1,y,z);
	tad[y]=v;
	if(lc[y]){
		if(tad[y]<0){
			lhz[lc[y]].l=lhz[lc[y]].r=lhz[lc[y]].maxn=tad[y];
			lhz[lc[y]].pre=tad[y]*size[lc[y]];
		}
		else{
			lhz[lc[y]].l=lhz[lc[y]].r=lhz[lc[y]].maxn=lhz[lc[y]].pre=tad[y]*size[lc[y]];
		}
	}
	else{
		if(tad[y]<0){
			lhz[rc[y]].l=lhz[rc[y]].r=lhz[rc[y]].maxn=tad[y];
			lhz[rc[y]].pre=tad[y]*size[rc[y]];
		}
		else{
			lhz[rc[y]].l=lhz[rc[y]].r=lhz[rc[y]].maxn=lhz[rc[y]].pre=tad[y]*size[rc[y]];
		}
	}
	root=Merge(Merge(x,y),z);
}
void reserve(int p,int tot){
	int x,y,z;
	int l=p,r=p+tot-1;
	Split(root,l-1,x,y);
	Split(root,r-l+1,y,z);
	swap(lc[y],rc[y]);
	lazy[y]^=1;
	root=Merge(Merge(x,y),z);
}
int ask_pre(int p,int tot){
	int x,y,z;
	int l=p,r=p+tot-1;
	Split(root,l-1,x,y);
	Split(root,r-l+1,y,z);
	int res=lhz[y].pre;
	root=Merge(Merge(x,y),z);
	return res;
}
int ask_ziduanhe(){
	return lhz[root].maxn;
}
int n,m,length,p,c;
int main(){
	srand(time(0));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&change[i]);
	root=build(1,n);
	while(m--){
		scanf("%s",op);
		if(op[0]=='M'&&op[2]=='X'){
			printf("%d\n",ask_ziduanhe());
			continue;
		}
		scanf("%d%d",&p,&length);
		if(op[0]=='I'){
			for(int i=1;i<=length;i++)scanf("%d",&change[i]);
			insert(p,length);
		}
		else if(op[0]=='D') erase(p,length);
		else if(op[0]=='M'&&op[2]=='K'){
			scanf("%d",&c);
			update(p,length,c);
		}
		else if(op[0]=='R')reserve(p,length);
		else printf("%d\n",ask_pre(p,length));
	}
}
2023/1/12 18:29
加载中...