[NOI2005]维护数列

终于过了。。调了一天了。。

嗯,记一下有哪些坑点:

首先,MAKE-SAME操作可以是设为0,这里要注意一下。

回收点的时候要注意把标记清空。

还有边界的inf要设的合理一点。

然后就没了。。我的一天啊。。

奉上我丑陋无比的代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define lch ch[root][0]
#define rch ch[root][1]
using namespace std;

inline char gc() {
//	static char buf[100000],*p1,*p2;
//	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	return getchar();
}

template<class T>
int read(T &ans) {
	ans=0;char ch=gc();T f=1;
	while(!isdigit(ch)) {
		if(ch==EOF) return -1;
		if(ch=='-') f=-1;
		ch=gc();
	}
	while(isdigit(ch))
		ans=ans*10+ch-'0',ch=gc();
	ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}

void skip() {
	char ch=gc();
	while(ch!='
'&&ch!=' ') ch=gc();
}

int get_opt() {
	char ch=gc();
	while(!isalpha(ch)) ch=gc();
	if(ch=='M') {
		gc();ch=gc();
		skip();
		if(ch=='K') return 3;
		else return 6;
	}
	skip();
	switch(ch) {
		case 'I' : return 1;
		case 'D' : return 2;
		case 'R' : return 4;
		case 'G' : return 5;
	}
}

typedef long long ll;
const int Maxn=510000;
const int inf=0x3f3f3f3f;

ll seed=20020414;

int rand() {
	seed^=seed<<32,seed^=seed>>15,seed^=seed<<3;
	return seed=((seed^1360893662)+371122200)*204140019+1098900342&0x7fffffff;
}

int ch[Maxn][2],siz[Maxn],lm[Maxn],rm[Maxn],dat[Maxn],sum[Maxn],ma[Maxn];
int rot,x,n,m,a[Maxn],rnd[Maxn],flag[Maxn],bj[Maxn],st[Maxn],pos,k,lt,rt,mt;
int q[Maxn],top;

void update(int root) {
	siz[root]=siz[lch]+siz[rch]+1;
	sum[root]=sum[lch]+sum[rch]+dat[root];
	lm[root]=max(lm[lch],sum[lch]+dat[root]+lm[rch]);
	rm[root]=max(rm[rch],sum[rch]+dat[root]+rm[lch]);
	ma[root]=lm[rch]+dat[root]+rm[lch];
	if(lch) qmax(ma[root],ma[lch]);
	if(rch) qmax(ma[root],ma[rch]);
}

int newnode(int x) {
	int root=q[top--];
	lch=rch=0;
	rnd[root]=rand();
	dat[root]=x;
	bj[root]=2333,flag[root]=0;
	update(root);
	return root;
}

void pushr(int root) {
	if(!root) return;
	flag[root]^=1;
	swap(lch,rch);
	swap(lm[root],rm[root]);
}

void abj(int root,int x) {
	if(!root) return;
	bj[root]=x;
	sum[root]=siz[root]*x;
	dat[root]=x;
	rm[root]=lm[root]=max(0,sum[root]);
	ma[root]=max(x,sum[root]);
}

void pushdown(int root) {
	if(bj[root]!=2333) {
		abj(lch,bj[root]);
		abj(rch,bj[root]);
		bj[root]=2333,flag[root]=0;
	}
	if(flag[root]) {
		flag[root]=0;
		pushr(lch),pushr(rch);
	}
}

int merge(int a,int b) {
	if(!a||!b) return a+b;int root;
	if(rnd[a]<rnd[b]) root=a,pushdown(root),rch=merge(rch,b);
	else root=b,pushdown(root),lch=merge(a,lch);update(root);return root;
}

void split(int root,int &a,int &b,int x) {
	if(!root) {a=b=0;return;}
	if(!x) {b=root,a=0;return;}
	pushdown(root);
	if(siz[lch]<x) a=root,split(rch,rch,b,x-siz[lch]-1);
	else b=root,split(lch,a,lch,x);update(root);
}

int build(int x) {
	int zhy=1;
	st[1]=newnode(a[1]);
	for(int i=2;i<=x;i++) {
		int root=newnode(a[i]);
		while(zhy&&rnd[st[zhy]]>=rnd[root]) lch=st[zhy--],update(lch);
		update(root);if(zhy) ch[st[zhy]][1]=root,update(st[zhy]);
		st[++zhy]=root;
	}
	while(zhy) update(st[zhy--]);
	return st[1];
}

void del(int root) {
	q[++top]=root;
	if(lch) del(lch);
	if(rch) del(rch);
}

void insert() {
	read(pos,k);if(!k) return;
	for(int i=1;i<=k;i++) read(a[i]);
	split(rot,lt,rt,pos+1);
	rot=merge(merge(lt,build(k)),rt);
}

void del() {
	read(pos,k);if(!k) return;
	split(rot,lt,rt,pos);
	split(rt,mt,rt,k);
	rot=merge(lt,rt);
	del(mt);
}

void chan() {
	read(pos,k,x);if(!k) return;
	split(rot,lt,rt,pos);
	split(rt,mt,rt,k);
	abj(mt,x);
	rot=merge(merge(lt,mt),rt);
}

void rev() {
	read(pos,k);if(!k) return;
	split(rot,lt,rt,pos);
	split(rt,mt,rt,k);
	pushr(mt);
	rot=merge(merge(lt,mt),rt);
}

void gsum() {
	read(pos,k);if(!k) {puts("0");return;}
	split(rot,lt,rt,pos);
	split(rt,mt,rt,k);
	printf("%d
",sum[mt]);
	rot=merge(merge(lt,mt),rt);
}

void gmax() {
	printf("%d
",ma[rot]);
}

void print(int root) {
	if(!root) return;
	printf("(");
	print(lch);
	printf(")");
	printf("%d",dat[root]);
	printf("{");
	print(rch);
	printf("}");
}

signed main() {
//	freopen("test.in","r",stdin);
//	freopen("out","w",stdout);
	read(n,m);a[1]=-510000000;
	for(int i=1;i<=n;i++) read(a[i+1]);a[n+2]=-510000000;
	for(int i=1;i<510000;i++) q[++top]=i;
	rot=build(n+2);
//	print(rot);putchar('
');
	while(m--) {
		switch(get_opt()) {
			case 1 : insert();break;
			case 2 : del();break;
			case 3 : chan();break;
			case 4 : rev();break;
			case 5 : gsum();break;
			case 6 : gmax();break;
		}
	}
//	update(rot);
//	print(rot);putchar('
');
	return 0;
}


原文地址:https://www.cnblogs.com/shanxieng/p/10250670.html