zoukankan      html  css  js  c++  java
  • 洛谷 P4146 序列终结者

    Description

    P4146 序列终结者

    Solution

    fhq-treap

    不得不说 (fhq-treap) 代码是真的短,真的好写。

    挺板子的一道题。

    • 区间加:打个 (add) 标记,不停下放即可,相应的 (maxs)(val)(add) 都要更新。

    • 区间翻转:这就是个文艺平衡树板子,不多说了。(不会的话,可以看一下我的博客 洛谷 P3391 【模板】文艺平衡树

    • 查询区间最大值:把区间对应的子树找出来,输出这个子树记录的最大值即可。

    注意 (pushup) 时要判断是否有左右子树,在向上传。

    Code

    #include <bits/stdc++.h>
    #define ls(x) t[x].ch[0]
    #define rs(x) t[x].ch[1]
    
    using namespace std;
    
    const int N = 5e4 + 10;
    int n, m, root, tot;
    struct Treap{
    	int ch[2], siz, maxs, val, wei, add, lazy;
    }t[N];
    int a, b, c;
    
    inline int read(){
    	int x = 0, f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar(); }
    	while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    	return x * f;
    }
    
    inline void pushup(int x){
    	t[x].siz = t[ls(x)].siz + t[rs(x)].siz + 1;
    	t[x].maxs = t[x].val;
    	if(ls(x)) t[x].maxs = max(t[x].maxs, t[ls(x)].maxs);
    	if(rs(x)) t[x].maxs = max(t[x].maxs, t[rs(x)].maxs);
    }
    
    inline void pushdown(int x){
    	if(!x) return;
    	if(t[x].lazy){
    		if(ls(x)) t[ls(x)].lazy ^= 1;
    		if(rs(x)) t[rs(x)].lazy ^= 1;
    		swap(ls(x), rs(x));
    		t[x].lazy = 0;
    	}
    	if(t[x].add){
    		if(ls(x)) t[ls(x)].val += t[x].add, t[ls(x)].add += t[x].add, t[ls(x)].maxs += t[x].add;
    		if(rs(x)) t[rs(x)].val += t[x].add, t[rs(x)].add += t[x].add, t[rs(x)].maxs += t[x].add;
    		t[x].add = 0;
    	}
    }
    
    inline void split(int x, int k, int &a, int &b){
    	if(!x){
    		a = b = 0;
    		return;
    	}
    	pushdown(x);
    	if(k >= t[ls(x)].siz + 1){
    		a = x;
    		split(rs(x), k - t[ls(x)].siz - 1, rs(x), b);
    	}else{
    		b = x;
    		split(ls(x), k, a, ls(x));
    	}
    	pushup(x);
    }
    
    inline int merge(int x, int y){
    	if(!x || !y) return x | y;
    	if(t[x].wei <= t[y].wei){
    		pushdown(x);
    		rs(x) = merge(rs(x), y);
    		pushup(x);
    		return x;
    	}else{
    		pushdown(y);
    		ls(y) = merge(x, ls(y));
    		pushup(y);
    		return y;
    	}
    }
    
    inline int newnode(int k){
    	t[++tot].val = t[tot].maxs = k, t[tot].siz = 1, t[tot].wei = rand();
    	return tot;
    }
    
    inline void insert(int k){
    	root = merge(root, newnode(k));
    }
    
    inline void Add(int l, int r, int k){
    	int len = r - l + 1;
    	split(root, l - 1, a, b);
    	split(b, len, b, c);
    	t[b].maxs += k;
    	t[b].val += k;
    	t[b].add += k;
    	root = merge(merge(a, b), c);
    }
    
    inline void Reverse(int l, int r){
    	split(root, l - 1, a, b);
    	split(b, r - l + 1, b, c);
    	t[b].lazy ^= 1;
    	root = merge(merge(a, b), c);
    }
    
    inline int Query(int l, int r){
    	split(root, l - 1, a, b);
    	split(b, r - l + 1, b, c);
    	int ans = t[b].maxs;
    	root = merge(merge(a, b), c);
    	return ans;
    }
    
    int main(){
    	n = read(), m = read();
    	for(int i = 1; i <= n; i++)
    		insert(0);
    	while(m--){
    		int op = read(), l = read(), r = read(), k;
    		if(op == 1) k = read(), Add(l, r, k);
    		else if(op == 2) Reverse(l, r);
    		else printf("%d
    ", Query(l, r));
    	}
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15157574.html

  • 相关阅读:
    快速浏览教材《计算机科学概论》提问
    2020-2021-1 20201329 《信息安全专业导论》第一周学习总结
    《密码与安全新技术专题》第一周作业
    《网络攻防》准备阶段
    20175312 2018-2019-2 《Java程序设计》第10、11周学习总结
    20175312 2018-2019-2 实验三 敏捷开发与XP实践 实验报告
    MyCP(课下作业,必做)
    20175312 2018-2019-2 《Java程序设计》第9周学习总结
    20175312 2018-2019-2 《Java程序设计》第8周学习总结
    20175312 2018-2019-2 实验二 面向对象程序设计 实验报告
  • 原文地址:https://www.cnblogs.com/xixike/p/15157574.html
Copyright © 2011-2022 走看看