BZOJ 1251 绳命中第一道SPLAY
2015-12-25 16:23
169 查看
不要问蒟蒻标题是怎么回事。蒟蒻就是蒟蒻,T^T到现在才会写SPLAY。
感觉这道题的SPLAY也没啥好讲的,很基础。第一次写SPLAY,不过思路还是比较明朗。只不过最开始写这道题的时候傻乎乎的只给“加”的操作打标记,没给“翻转”打标记,T了一次。再加上自己这凌乱的代码、数不清的细节错误,调了老长时间。
有这么一些值得我注意的细节:
find()过程中要pushdown
rotate()前要分别pushdown父节点和当前节点,之后要分别maintain父节点和当前节点
rotate()过程中别忘了P[fa].fa的一个字节点指针要改变
合并和分裂操作过程中也要pushdown和maintain
注意P[0]的值不要影响有效的节点的值的计算
感觉这道题的SPLAY也没啥好讲的,很基础。第一次写SPLAY,不过思路还是比较明朗。只不过最开始写这道题的时候傻乎乎的只给“加”的操作打标记,没给“翻转”打标记,T了一次。再加上自己这凌乱的代码、数不清的细节错误,调了老长时间。
有这么一些值得我注意的细节:
find()过程中要pushdown
rotate()前要分别pushdown父节点和当前节点,之后要分别maintain父节点和当前节点
rotate()过程中别忘了P[fa].fa的一个字节点指针要改变
合并和分裂操作过程中也要pushdown和maintain
注意P[0]的值不要影响有效的节点的值的计算
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; void get (int &x) { char c = getchar(); bool neg = 0; x = 0; while (c < '0' || c > '9') {if (c == '-') neg = 1; c = getchar();} while (c <= '9' && c >= '0') x = x*10+c-48, c = getchar(); if (neg) x = -x; } void put (int x) { if (x < 0) {putchar ('-'); x = -x;} if (x == 0) {putchar ('0');} char s[15]; int num = 0; while (x) s[++num] = (x%10)+48, x /= 10; while (num) putchar (s[num--]); putchar ('\n'); } struct node { int k, lc, rc, fa, sz, ad, re, mx; void reset() {k=lc=rc=fa=sz=ad=re=0; mx=-(1<<30);} }; struct SplayTree { node P[50005]; int cnt, root; void build (int rt, int sz) { P[rt].sz = sz; int half = sz>>1; if (half) {P[++cnt].fa=rt, P[rt].lc=cnt; build(cnt,half);} half = sz - half - 1; if (half) {P[++cnt].fa=rt, P[rt].rc=cnt; build(cnt,half);} } void initialize (int sz) {build(cnt=root=1, sz);} void pushdown (int rt) { if (P[rt].ad) { int ad = P[rt].ad, lc = P[rt].lc, rc = P[rt].rc; P[lc].k += ad, P[lc].ad += ad, P[lc].mx += ad; P[rc].k += ad, P[rc].ad += ad, P[rc].mx += ad; P[rt].ad = 0; } if (P[rt].re) { int lc = P[rt].lc, rc = P[rt].rc; swap(P[lc].lc, P[lc].rc); swap(P[rc].lc, P[rc].rc); P[lc].re ^= 1, P[rc].re ^= 1; P[rt].re = 0; } } void maintain (int rt) { P[0].reset(); int lc = P[rt].lc, rc = P[rt].rc; P[rt].sz = P[lc].sz + P[rc].sz + 1; P[rt].mx = max (max(P[lc].mx,P[rc].mx), P[rt].k); } int find (int rt, int k) { int rk = P[P[rt].lc].sz+1; if (rk == k) return rt; pushdown(rt); if (rk > k) return find (P[rt].lc, k); if (rk < k) return find (P[rt].rc, k-rk); } void rotate (int rt) { int fa = P[rt].fa, gfa = P[fa].fa; pushdown(fa); pushdown(rt); if (P[fa].lc == rt) { P[fa].lc = P[rt].rc, P[P[rt].rc].fa = fa; P[rt].rc = fa, P[fa].fa = rt; } else { P[fa].rc = P[rt].lc, P[P[rt].lc].fa = fa; P[rt].lc = fa, P[fa].fa = rt; } if(P[gfa].lc==fa) P[gfa].lc=rt; else P[gfa].rc=rt; P[rt].fa = gfa; if (fa == root) root = rt, P[rt].fa = 0; maintain(fa); maintain(rt); } void splay (int rt) { while(rt!=root) { int fa = P[rt].fa, gfa = P[fa].fa; if(gfa&&(P[fa].lc==rt)==(P[gfa].lc==fa)) rotate(fa); rotate(rt); } } void merge (int L, int R) { if (!L) {root=R; return;} if (!R) {root=L; return;} root = L; splay (find(L,P[L].sz)); pushdown (root); P[root].rc = R, P[R].fa = root; maintain (root); } int split (int k, bool po) { int rt = find (root, k), t; splay (rt); pushdown (rt); if (po) t=P[rt].lc, P[rt].lc=0; else t=P[rt].rc, P[rt].rc=0; P[t].fa = 0; maintain(rt); return t; } void add (int L, int R, int V) { int op = split(L,1), op2 = split(R-L+1,0); P[root].k+=V, P[root].mx+=V, P[root].ad+=V; merge (root,op2); merge (op, root); } void rever (int L, int R) { int op = split(L,1), op2 = split(R-L+1,0); swap(P[root].lc, P[root].rc); P[root].re ^= 1; merge (root,op2); merge (op, root); } void getmax (int L, int R) { int op = split(L,1), op2 = split(R-L+1,0); put (P[root].mx); merge (root,op2); merge (op, root); } }Solve; int n, m; int main () { get (n); get (m); Solve.initialize(n); while (m--) { int cmd, L, R, V; get (cmd); get (L); get (R); if (cmd == 1) {get (V); Solve.add(L,R,V);} if (cmd == 2) Solve.rever(L,R); if (cmd == 3) Solve.getmax(L,R); } return 0; }
相关文章推荐
- php curl_init函数用法
- [置顶] 大型网站技术架构(六)网站的伸缩性架构
- [置顶] 大型网站技术架构(六)网站的伸缩性架构
- 大型网站技术架构(六)网站的伸缩性架构
- Exchange Server 2016 之七:体系结构
- iOS开发-调整文字之间间距
- 一行代码让无边框窗体实现阴影
- UITableView - beginUpdates和endUpdates方法
- For Path
- CF 600E Lomsat gelral 学习内容
- 【spring-security】nested exception is java.lang.ClassNotFoundException: org.springframework.security.
- windows2008 nps+802.1
- Yii2 集成ueditor脚手架
- 非线性规划
- Windows perl dbi oracle环境配置
- 购物车实现逻辑
- 二叉搜索树的后序遍历序列
- MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决
- Caffe学习系列(10):命令行解析
- 机器学习(二):分类算法之k-近邻算法