• [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;
    }
    
    
    
  • 相关阅读:
    WPF 关于多语言 的实现 学习,利用反射中的特性
    WPF Textbox 中文输入崩溃 规避
    自定义控件.依赖项属性同步更新内部控件属性
    HexInput
    HashMap实现原理分析
    centos下nginx安装
    dos下mybatis自动生成代码
    设计模式之装饰器模式
    Java 中的悲观锁和乐观锁的实现
    redis分布式锁
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10250670.html
Copyright © 2020-2023  润新知