[BZOJ 1251] 序列终结者
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1251
[算法]
伸展树
时间复杂度 : O(MlogN)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 50010 #define LRSON Tree[Tree[root].son[1]].son[0] const int INF = 2e9; int n , m; template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } struct Splay { int root , total; struct Node { int fa , son[2]; int sz , mx , tag , val; bool rev; } Tree[MAXN << 1]; inline void init() { root = total = 0; for (int i = 0; i < MAXN; i++) { Tree[i].fa = Tree[i].son[0] = Tree[i].son[1] = 0; Tree[i].sz = Tree[i].val = Tree[i].tag = 0; Tree[i].mx = -INF; Tree[i].rev = false; } } inline void push_back(int x) { if (!root) { root = ++total; Tree[root].sz = 1; Tree[root].mx = Tree[root].val = x; return; } int now = root; while (Tree[now].son[1]) now = Tree[now].son[1]; Tree[now].son[1] = ++total; Tree[total].fa = now; Tree[total].sz = 1; Tree[total].mx = Tree[total].val = x; splay(total,0); } inline void update(int x) { Tree[x].sz = Tree[Tree[x].son[0]].sz + Tree[Tree[x].son[1]].sz + 1; Tree[x].mx = Tree[x].val; if (Tree[x].son[0]) Tree[x].mx = max(Tree[x].mx,Tree[Tree[x].son[0]].mx); if (Tree[x].son[1]) Tree[x].mx = max(Tree[x].mx,Tree[Tree[x].son[1]].mx); } inline void pushdown(int x) { if (Tree[x].rev) { swap(Tree[x].son[0],Tree[x].son[1]); Tree[Tree[x].son[0]].rev ^= true; Tree[Tree[x].son[1]].rev ^= true; Tree[x].rev = false; } if (Tree[x].tag) { Tree[Tree[x].son[0]].tag += Tree[x].tag; Tree[Tree[x].son[1]].tag += Tree[x].tag; Tree[Tree[x].son[0]].val += Tree[x].tag; Tree[Tree[x].son[1]].val += Tree[x].tag; Tree[Tree[x].son[0]].mx += Tree[x].tag; Tree[Tree[x].son[1]].mx += Tree[x].tag; Tree[x].tag = 0; } } inline void rotate(int x) { int f = Tree[x].fa , g = Tree[f].fa; int tmpx = get(x) , tmpf = get(f); pushdown(f); pushdown(x); if (!f) return; Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1]; if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].fa = f; Tree[x].son[tmpx ^ 1] = f; Tree[f].fa = x; Tree[x].fa = g; if (g) Tree[g].son[tmpf] = x; update(f); update(x); } inline bool get(int x) { return Tree[Tree[x].fa].son[1] == x; } inline void splay(int x,int pos) { for (int f = Tree[x].fa; (f = Tree[x].fa) != pos; rotate(x)) { if (Tree[f].fa != pos) rotate(get(f) == get(x) ? f : x); } if (!pos) root = x; } inline int find(int k) { int now = root; while (now > 0) { pushdown(now); if (k <= Tree[Tree[now].son[0]].sz) now = Tree[now].son[0]; else { int size = Tree[Tree[now].son[0]].sz + 1; if (k == size) return now; k -= size; now = Tree[now].son[1]; } } } inline void add(int l,int r,int value) { int pl = find(l - 1) , pr = find(r + 1); splay(pl,0); splay(pr,root); Tree[LRSON].tag += value; Tree[LRSON].mx += value; Tree[LRSON].val += value; update(Tree[root].son[1]); update(root); } inline void reverse(int l,int r) { int pl = find(l - 1) , pr = find(r + 1); splay(pl,0); splay(pr,root); Tree[LRSON].rev ^= true; } inline int query(int l,int r) { int pl = find(l - 1) , pr = find(r + 1); splay(pl,0); splay(pr,root); return Tree[LRSON].mx; } } T; int main() { read(n); read(m); T.init(); T.push_back(-INF); for (int i = 1; i <= n; i++) T.push_back(0); T.push_back(-INF); while (m--) { int op; read(op); if (op == 1) { int l , r , value; read(l); read(r); read(value); T.add(l + 1,r + 1,value); } if (op == 2) { int l , r; read(l); read(r); T.reverse(l + 1,r + 1); } if (op == 3) { int l , r; read(l); read(r); printf("%d\n",T.query(l + 1,r + 1)); } } return 0; }