• BZOJ 1500: [NOI2005] 维修数列


    Input

    输入的第 1 行包含两个数 N 和 M(M ≤20 000),N 表示初始时数列中数的个数,M 表示要进行的操作数目。
    第 2 行包含 N 个数字,描述初始时的数列。
    以下 M 行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有 500 000 个数,数列中任何一个数字均在 [-1 000, 1 000] 内。
    插入的数字总数不超过 4 000 000 个,输入文件大小不超过 20MBytes。

    Output

    对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10


    传说中巨变态的一道题。。。调了一下午终于AC了。。。模板:Orz神犇黄学长 @hzwer

    血的教训:

    边界值一定要初始化!边界值一定要初始化!边界值一定要初始化!重要的事情说三遍!

    放代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 1000005, INF = 0x3f3f3f3f;
    int N, M, root, spa[MAXN], top, A[MAXN], id[MAXN], tot;
    int rd(){
    	int x=0, f=0, ch = getchar();
    	while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();};
    	while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();};
    	return f?-x:x;
    }
    struct SplayTree{
    	int fa[MAXN], ch[MAXN][2];
    	int v[MAXN], sz[MAXN], sum[MAXN], lx[MAXN], rx[MAXN], mx[MAXN];	
    	int cov[MAXN], rev[MAXN];
    	
    	void trace(){
    		printf("root=%d, tot=%d
    ", root, tot);
    		for(int i = 0; i <= N+2; ++i){
    			printf("%d: ", i);
    			printf("fa=%d, ch[0]=%d, ch[1]=%d, v=%d, sz=%d,
    ",
    			fa[i], ch[i][0], ch[i][1], v[i], sz[i]);
    			printf("sum=%d, lx=%d, rx=%d, mx=%d, cov=%d, rev=%d;
    ",
    			sum[i], lx[i], rx[i], mx[i], cov[i], rev[i]);
    		}
    	}
    	void dfs(int x){
    		if(x == 0) return;
    		dfs(ch[x][0]);
    		if(v[x] != -INF)printf("%d ", v[x]);
    		dfs(ch[x][1]);
    	}
    	void pushup(int x){
    		int l = ch[x][0], r = ch[x][1];
    		sz[x] = 1 + sz[l] + sz[r];
    		sum[x] = v[x] + sum[l] + sum[r];
    		lx[x] = max(lx[l], sum[l] + v[x] + lx[r]);
    		rx[x] = max(rx[r], sum[r] + v[x] + rx[l]);
    		mx[x] = max(rx[l] + v[x] + lx[r], max(mx[l], mx[r]));
    	}
    	void pushdown(int x){
    		int l = ch[x][0], r = ch[x][1];
    		if(cov[x] != INF){
    			if(l){
    				v[l] = cov[x];
    				sum[l] = sz[l] * cov[x];
    				lx[l] = rx[l] = cov[x] > 0 ? sum[l] : 0;
    				mx[l] = cov[x] > 0 ? sum[l] : cov[x];
    				cov[l] = cov[x]; rev[l] = 0;
    			}
    			if(r){
    				v[r] = cov[x];
    				sum[r] = sz[r] * cov[x];
    				lx[r] = rx[r] = cov[x] > 0 ? sum[r] : 0;
    				mx[r] = cov[x] > 0 ? sum[r] : cov[x];
    				cov[r] = cov[x]; rev[r] = 0;
    			}
    			cov[x] = INF; rev[x] = 0;
    		}
    		else if(rev[x]){
    			rev[l] ^= 1; rev[r] ^= 1; rev[x] = 0;
    			swap(lx[l], rx[l]); swap(lx[r], rx[r]);
    			swap(ch[l][0], ch[l][1]); swap(ch[r][0], ch[r][1]);
    		}
    	}
    	void rot(int x, int &k){
    		int y = fa[x], z = fa[y], l = ch[y][1] == x, r = l ^ 1;
    		if(y == k) k = x;
    		else ch[z][ch[z][1] == y] = x;
    		fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
    		ch[y][l] = ch[x][r]; ch[x][r] = y;
    		pushup(y); pushup(x);
    	}
    	void splay(int x, int &k){
    		while(x != k){
    			int y = fa[x], z = fa[y];
    			if(y != k){
    				if((ch[y][1] == x) ^ (ch[z][1] == y)) rot(x, k);
    				else rot(y, k);
    			}
    			rot(x, k);
    		}
    	}
    	int srch(int x, int k){
    		pushdown(x);
    		int l = ch[x][0], r = ch[x][1];
    		if(k == sz[l] + 1) return x;
    		if(k <= sz[l]) return srch(l, k);
    		return srch(r, k - sz[l] - 1);
    	}
    	int &split(int k, int t){
    		int x = srch(root, k), y = srch(root, k + t + 1);
    		splay(x, root); splay(y, ch[x][1]);
    		return ch[y][0];
    	}
    	void build(int &x, int f, int L, int R){
    		if(L > R) return;
    		if(L == R){
    			x = id[L]; fa[x] = f; v[x] = sum[x] = mx[x] = A[L];
    			sz[x] = 1; cov[x] = INF; rev[x] = 0;
    			if(A[L] > 0) lx[x] = rx[x] = A[L];
    			else lx[x] = rx[x] = 0;
    			return;
    		}
    		int mid = (L + R) >> 1;
    		x = id[mid]; fa[x] = f; v[x] = A[mid]; cov[x] = INF; rev[x] = 0;
    		build(ch[x][0], x, L, mid-1);
    		build(ch[x][1], x, mid+1, R);
    		pushup(x);
    	}
    	void ins(){
    		int k = rd(), t = rd(), x, y;
    		for(int i = 1; i <= t; ++i){
    			A[i] = rd();
    			id[i] = top ? spa[--top] : ++tot; 
    		}
    		x = srch(root, k+1), y = srch(root, k+2);
    		splay(x, root); splay(y, ch[x][1]);
    		build(ch[y][0], y, 1, t);
    		pushup(y); pushup(x);
    	}
    	void rec(int x){
    		if(!x) return;
    		rec(ch[x][0]); rec(ch[x][1]); 
    		fa[x] = ch[x][0] = ch[x][1] = 0;
    		cov[x] = INF; rev[x] = 0;
    		spa[top++] = x;
    	}
    	void del(){
    		int k = rd(), t = rd();
    		int &x = split(k, t), y = fa[x];
    		rec(x); x = 0;
    		pushup(y); pushup(fa[y]);
    	}
    	void modify(){
    		int k = rd(), t = rd(), c = rd();
    		int &x = split(k, t), y = fa[x];
    		cov[x] = v[x] = c; sum[x] = c * sz[x]; rev[x] = 0;
    		if(c < 0){
    			lx[x] = rx[x] = 0; mx[x] = c;
    		}else{
    			lx[x] = rx[x] = mx[x] = sum[x];
    		}
    		pushup(y); pushup(fa[y]);
    	}
    	void rever(){
    		int k = rd(), t = rd();
    		int x = split(k, t), y = fa[x];
    		rev[x] ^= 1;
    		swap(ch[x][0], ch[x][1]);
    		swap(lx[x], rx[x]);
    		pushup(y); pushup(fa[y]);
    	}
    	void gsum(){
    		int k = rd(), t = rd();
    		if(t == 0){printf("0
    "); return; }
    		int x = split(k, t);
    		printf("%d
    ", sum[x]);
    	}
    	void gmax(){
    		printf("%d
    ", mx[root]);
    	}
    }spt;
    
    char opt[128];
    int main(){
    	freopen("sequence9.in", "r", stdin);
    	freopen("my.txt", "w", stdout);
    	scanf("%d%d", &N, &M);
    	for(int i = 2; i <= N + 1; ++i){
    		A[i] = rd(); id[i] = ++tot;
    	}
    	spt.mx[0] = A[1] = A[N+2] = -INF; id[1] = ++tot; id[N+2] = ++tot;	//重要! 
    	spt.build(root, 0, 1, N+2);
    	memset(spt.cov, 0x3f, sizeof(spt.cov));
    	for(int i = 1; i <= M; ++i){
    //		spt.trace();
    //		spt.dfs(root); putchar('
    ');
    		scanf("%s", opt);
    //		printf("%d: %s %d
    ", i, opt, spt.sz[root]);
    		switch(opt[0]){
    			case 'I':
    				spt.ins();
    				break;
    			case 'D':
    				spt.del();
    				break;
    			case 'R':
    				spt.rever();
    				break;
    			case 'G':
    				spt.gsum();
    				break;
    			case 'M':
    				if(opt[2] == 'K'){
    					spt.modify();
    				}else{
    					spt.gmax();
    				}
    				break;
    		}
    	}
    	return 0;
    }
    


  • 相关阅读:
    【excel】=EXACT(A1,B1) 比较两个字符串是否相等
    【oracle】oracle11g安装失败 提示找不到文件,模板General_Purpose.dbc不存在
    【oracle】11g服务器安装详细步骤
    【oracle】ceil函数 返回值 (大于参数的最小整数)
    【oracle】 months_between(date1,date2)
    javaWeb遍历获取session中的值
    tomcat+mysql数据库连接池的操作
    java中值得类型转化
    javaWeb图片验证码代码
    JSP与Servlet之间传值
  • 原文地址:https://www.cnblogs.com/will7101/p/6506687.html
Copyright © 2020-2023  润新知