[Splay] NOI2005 维修数列

BZOJ 1500

不想说有多心酸

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;

inline char nc()
{
	static char buf[100000],*p1=buf,*p2=buf;
	if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
	return *p1++;
}

inline void read(int &x)
{
	char c=nc(),b=1;
	for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
	for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline void read(char *s)
{
	char c=nc(); int len=0;
	for (;!((c>='A' && c<='Z') || c=='-');c=nc());
	for (;(c>='A' && c<='Z') || c=='-';s[++len]=c,c=nc()); s[++len]=0;
}

struct Splay{
	#define oo 1<<30
	#define ND_MAX 600005
	struct node{
		node *p,*ch[2];
		int val,size;
		int fan,H;
		ll sum,smax,lmax,rmax;
		bool dir() { return p->ch[1]==this; }
		void setc(node *x,int d) { ch[d]=x; x->p=this; }
		void update(){
			size=ch[0]->size+ch[1]->size+1;
			sum=ch[0]->sum+ch[1]->sum+val;
			smax=max(ch[0]->smax,ch[1]->smax);
			smax=max(smax,ch[0]->rmax+val+ch[1]->lmax);
			lmax=max(ch[0]->lmax,ch[0]->sum+val+ch[1]->lmax);
			rmax=max(ch[1]->rmax,ch[1]->sum+val+ch[0]->rmax);	
		}
		void pushdown(node *null){
			if (fan)
			{
				if (ch[0]!=null) ch[0]->fan^=1,swap(ch[0]->ch[0],ch[0]->ch[1]),swap(ch[0]->lmax,ch[0]->rmax);
				if (ch[1]!=null) ch[1]->fan^=1,swap(ch[1]->ch[0],ch[1]->ch[1]),swap(ch[1]->lmax,ch[1]->rmax);
				fan=0;
			}
			if (H!=10000)
			{
				if (ch[0]!=null) 
					ch[0]->H=ch[0]->val=H,ch[0]->sum=ch[0]->size*H;
				if (ch[1]!=null) 
					ch[1]->H=ch[1]->val=H,ch[1]->sum=ch[1]->size*H;
				if (H>0)
				{
					if (ch[0]!=null) ch[0]->smax=ch[0]->lmax=ch[0]->rmax=ch[0]->sum;
					if (ch[1]!=null) ch[1]->smax=ch[1]->lmax=ch[1]->rmax=ch[1]->sum;
				}
				else
				{
					if (ch[0]!=null) ch[0]->smax=ch[0]->H,ch[0]->lmax=ch[0]->rmax=0;
					if (ch[1]!=null) ch[1]->smax=ch[1]->H,ch[1]->lmax=ch[1]->rmax=0;
				}
				H=10000;
			}
		}
	}*root,*null;
	node Mem[ND_MAX],*Stack[ND_MAX];
	int top;
	inline node *init_Memory(){
		for (int i=0;i<ND_MAX;i++) Stack[i]=Mem+i;
		top=ND_MAX-1;
		return Stack[top--];
	}
	inline node *New_Node(int key){
		node *p=Stack[top--];
		p->p=p->ch[0]=p->ch[1]=null;
		p->size=1; p->val=key;
		p->fan=0; p->H=10000;
		p->sum=p->smax=key;
		if (key>0) p->lmax=p->rmax=key; else p->lmax=p->rmax=0;
		return p;
	}
	inline void Del_Node(node *x){
		Stack[++top]=x;
	}
	Splay(){
		null=init_Memory(); 
		null->p=null->ch[0]=null->ch[1]=null; 
		null->size=0; null->sum=0;
		null->smax=-oo;
		null->lmax=null->rmax=0;
		root=null;
	}
	inline void clear(node *x) {
		if (x==null) return;
		if (x==root) root=null;
		clear(x->ch[0]);
		clear(x->ch[1]);
		if (x->p!=null) x->p->ch[x->dir()]=null,x->p->update();
		Del_Node(x);
	}
	inline void rot(node *x){
		if (x==null) return;
		if (x->p==root) root=x;
		bool d=x->dir(); node *p=x->p;
		if (p->p!=null) p->p->setc(x,p->dir()); else x->p=null;
		p->setc(x->ch[d^1],d); x->setc(p,d^1); p->update(); x->update();
	}
	inline void Pushdown(node *x){
		if (x->p!=null) Pushdown(x->p);
		x->pushdown(null);
	}
	inline void splay(node *&rt,node *x){
		if (x==null) return;
		Pushdown(x);
		while (x!=rt)
			if (x->p==rt)
				rot(x);
			else
				x->dir()==x->p->dir()?(rot(x->p),rot(x)):(rot(x),rot(x));
//		x->update();
	}
	inline node *build(int *a,int l,int r){
		int mid=(l+r)>>1;
		node *p=New_Node(a[mid]);
		if (l<=mid-1) p->setc(build(a,l,mid-1),0);
		if (mid+1<=r) p->setc(build(a,mid+1,r),1);
		p->update(); 
		return p;
	}
	inline node *findkth(node *rt,int k){
		if (rt->size<k) return null;
		node *x=rt;
		while (k)
		{
			x->pushdown(null);
			if (x->ch[0]->size+1==k)	
				break;
			else
				x->ch[0]->size+1<k?(k-=x->ch[0]->size+1,x=x->ch[1]):x=x->ch[0];
		}
		splay(root,x); return x;
	}
	inline void print(node *x){
		if (x==null) return;
//		x->pushdown(null);
		if (x->fan) 
			printf("*");
		if (x->H!=10000)
			printf("[%d]",x->H);
		if (x->val==-oo)
			printf("-oo");
		else
			printf("%d",x->val);
		putchar('('); print(x->ch[0]); putchar(')');
		putchar('('); print(x->ch[1]); putchar(')');
	}
}splay;

int n,m;
int a[500005];

int main()
{
	char ch[15];
	Splay::node *t1,*t2,*t;
	int l,r,c,_n;
	freopen("t.in","r",stdin);
	freopen("t.out","w",stdout);
	read(n); read(m);
	for (int i=1;i<=n;i++) read(a[i]);
	a[0]=-1<<30; a[++n]=-1<<30; 
	splay.root=splay.build(a,0,n); n--;
//	splay.print(splay.root); printf("\n");
	while (m--)
	{
		read(ch);
		if (!strcmp(ch+1,"INSERT"))
		{
			read(l); l++; r=l+1;
			read(_n); n+=_n;
			for (int i=1;i<=_n;i++) read(a[i]);
			t1=splay.findkth(splay.root,l); t2=splay.findkth(splay.root,r);
			splay.splay(splay.root,t1);
			splay.splay(splay.root->ch[1],t2);
//			splay.print(splay.root); printf("\n");
			t=splay.root->ch[1];
			t->setc(splay.build(a,1,_n),0);
			splay.root->ch[1]->update(); splay.root->update();
//			splay.print(splay.root); printf("\n");
		}
		else if (!strcmp(ch+1,"DELETE"))
		{
			read(l); read(r); n-=r; r=l+r+1;
			t1=splay.findkth(splay.root,l); t2=splay.findkth(splay.root,r);
			splay.splay(splay.root,t1);
			splay.splay(splay.root->ch[1],t2);
//			splay.print(splay.root); printf("\n");
			t=splay.root->ch[1]->ch[0];
			splay.clear(t);
			splay.root->ch[1]->update(); splay.root->update();
//			splay.print(splay.root); printf("\n");
		}
		else if (!strcmp(ch+1,"MAKE-SAME"))
		{
			read(l); read(r); r=l+r+1; read(c);
			t1=splay.findkth(splay.root,l); t2=splay.findkth(splay.root,r);
			splay.splay(splay.root,t1);
			splay.splay(splay.root->ch[1],t2);
//			splay.print(splay.root); printf("\n");
			t=splay.root->ch[1]->ch[0];
			t->H=t->val=c;
			t->sum=t->size*c;
			if (c>0)
				t->smax=t->lmax=t->rmax=t->sum;
			else
				t->smax=t->H,t->lmax=t->rmax=0;
			splay.root->ch[1]->update(); splay.root->update();
//			splay.print(splay.root); printf("\n");	
		}
		else if (!strcmp(ch+1,"REVERSE"))
		{
			read(l); read(r); r=l+r+1;
			t1=splay.findkth(splay.root,l); t2=splay.findkth(splay.root,r);
			splay.splay(splay.root,t1);
			splay.splay(splay.root->ch[1],t2);
//			splay.print(splay.root); printf("\n");
			t=splay.root->ch[1]->ch[0];
			t->fan^=1;
			swap(t->ch[0],t->ch[1]); swap(t->lmax,t->rmax); 
			splay.root->ch[1]->update(); splay.root->update();
//			splay.print(splay.root); printf("\n");
		}
		else if (!strcmp(ch+1,"GET-SUM"))
		{
			read(l); read(r); r=l+r+1;
			t1=splay.findkth(splay.root,l); t2=splay.findkth(splay.root,r);
			splay.splay(splay.root,t1);
			splay.splay(splay.root->ch[1],t2);
//			splay.print(splay.root); printf("\n");
			t=splay.root->ch[1]->ch[0];
			printf("%lld\n",t->sum);
		}
		else if (!strcmp(ch+1,"MAX-SUM"))
		{
			printf("%lld\n",splay.root->smax);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值