ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P4146 序列终结者

2021-08-18 17:02:57  阅读:178  来源: 互联网

标签:ch 洛谷 终结者 int siz rs add ls P4146


Description

P4146 序列终结者

Solution

fhq-treap

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

挺板子的一道题。

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

  • 区间翻转:这就是个文艺平衡树板子,不多说了。(不会的话,建议先做一下板子)

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

注意 \(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\n", Query(l, r));
	}
	return 0;
}

End

标签:ch,洛谷,终结者,int,siz,rs,add,ls,P4146
来源: https://www.cnblogs.com/xixike/p/15157574.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有