[bzoj3153] sone1 AC纪念
来源:互联网 发布:红米手机怎么清除数据 编辑:程序博客网 时间:2024/06/06 01:54
bzoj3153 sone1
历时两天A掉此题,特作纪念。
代码
#include <bits/stdc++.h>typedef long long LL;#define FOR(i, a, b) for (int i = (a), i##_END_ = (b); i <= i##_END_; i++)#define DNF(i, a, b) for (int i = (a), i##_END_ = (b); i >= i##_END_; i--)template <typename Tp> void in(Tp &x) { char ch = getchar(), f = 1; x = 0; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') f = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= f;}template <typename Tp> bool chkmax(Tp &x, Tp y) {return x > y ? 0 : (x=y,1);}template <typename Tp> bool chkmin(Tp &x, Tp y) {return x < y ? 0 : (x=y,1);}template <typename Tp> Tp Max(Tp x, Tp y) {return x > y ? x : y;}template <typename Tp> Tp Min(Tp x, Tp y) {return x < y ? x : y;}const int MAXN = 200010;struct Tag { int k, b; Tag(int k = 1, int b = 0): k(k), b(b) {} Tag run(const Tag &another) const { return Tag(k * another.k, b * another.k + another.b); }};struct Data { int minx, maxx, sum, sz; Data(int sz = 0, int minx = 0x3f3f3f3f, int maxx = -0x3f3f3f3f, int sum = 0) :minx(minx), maxx(maxx), sum(sum), sz(sz) {} Data run(const Tag &another) const { if (minx > maxx) return *this; Data ret; ret.sum = sum * another.k + sz * another.b; ret.sz = sz; if (another.k < 0) { ret.minx = another.k * maxx + another.b; ret.maxx = another.k * minx + another.b; } else { ret.maxx = another.k * maxx + another.b; ret.minx = another.k * minx + another.b; } return ret; } Data run(const Data &another) const { Data ret; if (minx > maxx) return another; if (another.minx > another.minx) return *this; ret.sz = sz + another.sz; ret.sum = sum + another.sum; ret.minx = Min(minx, another.minx); ret.maxx = Max(maxx, another.maxx); return ret; }};struct Node { bool inner; bool is_rev; Node *ch[4], *fa; Tag tag_chain, tag_sub; Data data_chain, data_sub, data_all, my; void pushdown(); void update(); void add(); void del(); void push(); void pushO(); void pushI(); void splayO(); void splayI(); void rotate(int); void access(bool=false); bool is_top_out(); bool is_top_inn(); void makerot(); void push_rev(); void push_tag_chain(Tag); void push_tag_sub(Tag);} *to[MAXN];int n, m, rt;int input[MAXN][2], w[MAXN];int debug(Node *x){ FOR(i, 1, n) if (x == to[i]) return i; return 0;}void Node::pushO(){ assert(!inner); if (!is_top_out()) fa -> pushO(); pushdown();}void Node::pushI(){ //if (!inner) return; assert(inner); if (!is_top_inn()) fa -> pushI(); pushdown();}void initialize(){ FOR(i, 1, n) { to[i] = new Node; to[i] -> ch[0] = to[i] -> ch[1] = to[i] -> ch[2] = to[i] -> ch[3] = NULL; to[i] -> fa = NULL; to[i] -> inner = false; to[i] -> is_rev = false; to[i] -> tag_chain = to[i] -> tag_sub = Tag(); to[i] -> data_chain = to[i] -> data_sub = Data(); to[i] -> my = Data(1, w[i], w[i], w[i]); to[i] -> data_all = to[i] -> my.run(to[i] -> data_chain).run(to[i] -> data_sub); }}void Node::push(){ if (fa) fa -> push(); pushdown();}bool Node::is_top_out(){ return !fa || fa -> ch[0] != this && fa -> ch[1] != this;}bool Node::is_top_inn(){ //printf("%d %d\n", inner, fa); //printf("%d\n", fa != NULL); return !fa -> inner;}void Node::add(){ Node *tmp = fa; while (tmp -> ch[3] != NULL && (tmp -> inner || tmp == fa)) { tmp -> pushdown(); tmp = tmp -> ch[3]; } if (tmp != fa) assert(!tmp -> inner); if (tmp == fa) tmp -> ch[3] = this; else { tmp -> fa -> ch[3] = new Node; Node *&x = tmp -> fa -> ch[3]; x -> inner = true; x -> is_rev = false; x -> fa = tmp -> fa; x -> ch[0] = x -> ch[1] = NULL; x -> ch[2] = tmp; x -> ch[3] = this; tmp -> fa = fa = x; Node *tep = x; while (tep -> inner) { tep -> update(); tep = tep -> fa; } x -> splayI(); }}void Node::del(){ int t = fa -> ch[2] == this ? 2 : 3; if (fa -> ch[t] != this) { assert(fa -> ch[t] == this); } if (fa -> inner) {// Node *tt = fa; fa -> pushI(); Node *bro = fa -> ch[t ^ 1]; bro -> fa = fa -> fa; int tt = bro -> fa -> ch[2] == fa ? 2 : 3; assert(bro -> fa -> ch[tt] == fa); bro -> fa -> ch[tt] = bro; Node *tep = bro -> fa; while (tep -> inner) { tep -> update(); tep = tep -> fa; } if (bro -> fa -> inner) bro -> fa -> splayI(); delete fa; } else { fa -> pushdown(); fa -> ch[t] = NULL; }}//不负责update,只负责pushdownvoid Node::access(bool is){ push(); splayO(); pushdown(); if (ch[1] != NULL) ch[1] -> add(); ch[1] = NULL; update(); Node *x = this; while (x -> fa != NULL) { Node *tmp = x -> fa; while (tmp -> inner) tmp = tmp -> fa; if (!is) x -> del(); else is = false; //while (tmp -> inner) tmp = tmp -> fa; tmp -> splayO(); tmp -> pushdown(); if (tmp -> ch[1] != NULL) tmp -> ch[1] -> add(); x -> fa = tmp; tmp -> ch[1] = x; tmp -> update(); x = tmp; }}void Node::rotate(int dir){ Node *pa = fa; fa = pa -> fa; if (fa != NULL) { int t = (fa -> ch[0] == pa ? 0 : (fa -> ch[1] == pa ? 1 : (fa -> ch[2] == pa ? 2 : 3))); fa -> ch[t] = this; } pa -> ch[dir] = ch[dir ^ 1]; if (ch[dir ^ 1] != NULL) ch[dir ^ 1] -> fa = pa; ch[dir ^ 1] = pa; pa -> fa = this; pa -> update(); update();}void Node::splayO(){ assert(!inner); pushO(); while (!is_top_out()) { int t1 = fa -> ch[0] == this ? 0 : 1; if (!fa -> is_top_out()) { int t2 = fa -> fa -> ch[0] == fa ? 0 : 1; if (t1 == t2) fa -> rotate(t1), rotate(t1); else rotate(t1), rotate(t2); } else rotate(t1); }}void Node::splayI(){ assert(inner); pushI(); while (!is_top_inn()) { int t1 = fa -> ch[2] == this ? 2 : 3; if (!fa -> is_top_inn()) { int t2 = fa -> fa -> ch[2] == fa ? 2 : 3; if (t1 == t2) fa -> rotate(t1), rotate(t1); else rotate(t1), rotate(t2); } else rotate(t1); }}void Node::push_rev(){ is_rev ^= 1; std::swap(ch[0], ch[1]);}void Node::push_tag_chain(Tag x){ tag_chain = tag_chain.run(x); my = my.run(x); data_chain = data_chain.run(x); data_all = my.run(data_sub).run(data_chain);}void Node::push_tag_sub(Tag x){ tag_sub = tag_sub.run(x); //tag_chain = tag_chain.run(x); //my = my.run(x); data_sub = data_sub.run(x); //data_chain = data_chain.run(x); data_all = my.run(data_sub).run(data_chain);}void Node::update(){ data_sub = Data(); if (ch[0] != NULL) data_sub = data_sub.run(ch[0] -> data_sub); if (ch[1] != NULL) data_sub = data_sub.run(ch[1] -> data_sub); if (ch[2] != NULL) data_sub = data_sub.run(ch[2] -> data_all); if (ch[3] != NULL) data_sub = data_sub.run(ch[3] -> data_all); data_chain = Data(); if (ch[0] != NULL) data_chain = data_chain.run(ch[0] -> data_chain).run(ch[0] -> my); if (ch[1] != NULL) data_chain = data_chain.run(ch[1] -> data_chain).run(ch[1] -> my); data_all = my.run(data_sub).run(data_chain);}void Node::pushdown(){ if (is_rev) { if (ch[0] != NULL) ch[0] -> push_rev(); if (ch[1] != NULL) ch[1] -> push_rev(); is_rev = false; } { Tag &tag = tag_chain; if (tag.k != 1 || tag.b != 0) { if (ch[0] != NULL) ch[0] -> push_tag_chain(tag); if (ch[1] != NULL) ch[1] -> push_tag_chain(tag); tag = Tag(1, 0); } } { Tag &tag = tag_sub; if (tag.k != 1 || tag.b != 0) { if (ch[0] != NULL) ch[0] -> push_tag_sub(tag); if (ch[1] != NULL) ch[1] -> push_tag_sub(tag); if (ch[2] != NULL) { ch[2] -> push_tag_chain(tag); ch[2] -> push_tag_sub(tag); } if (ch[3] != NULL) { ch[3] -> push_tag_chain(tag); ch[3] -> push_tag_sub(tag); } tag = Tag(1, 0); } }}void Node::makerot(){ access(); splayO(); push_rev();}void link(Node *x, Node *y){ y -> access(); y -> pushdown(); x -> makerot(); x -> fa = y; x -> access(true);}void cut(Node *x, Node *y){ x -> makerot(); y -> access(); y -> splayO(); y -> pushdown(); x -> fa = y -> ch[0] = NULL; y -> update();}Node *find_rot(Node *x){ x -> access(); x -> splayO(); x -> pushdown(); while (x -> ch[0] != NULL) { x = x -> ch[0]; x -> pushdown(); } return x;}int main(){ in(n); in(m); FOR(i, 1, n - 1) { in(input[i][0]); in(input[i][1]); } FOR(i, 1, n) in(w[i]); initialize(); in(rt); FOR(i, 1, n - 1) { link(to[input[i][0]], to[input[i][1]]); } FOR(i, 1, m) { int tp; in(tp); to[rt] -> makerot(); //FOR(i, 1, n) // to[i] -> access(); //to[rt] -> splayO(); //printf("%d\n", to[rt] -> data_all.sz); if (tp == 0) { int x, y; in(x); in(y); to[x] -> access(); to[x] -> splayO(); if (x == rt) { to[x] -> push_tag_chain(Tag(0, y)); to[x] -> push_tag_sub(Tag(0, y)); } else { to[x] -> my = to[x] -> my.run(Tag(0, y)); if (to[x] -> ch[3] != NULL) { to[x] -> ch[3] -> push_tag_chain(Tag(0, y)); to[x] -> ch[3] -> push_tag_sub(Tag(0, y)); } if (to[x] -> ch[2] != NULL) { to[x] -> ch[2] -> push_tag_chain(Tag(0, y)); to[x] -> ch[2] -> push_tag_sub(Tag(0, y)); } to[x] -> update(); } } else if (tp == 1) { int x; in(x); rt = x; } else if (tp == 2) { int x, y, z; in(x); in(y); in(z); to[x] -> makerot(); to[y] -> access(); to[y] -> splayO(); to[y] -> push_tag_chain(Tag(0, z)); } else if (tp == 3) { int x; in(x); to[x] -> access(); Data ret = Data(); if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all); if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all); ret = ret.run(to[x] -> my); printf("%d\n", ret.minx); } else if (tp == 4) { int x; in(x); to[x] -> access(); Data ret = Data(); if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all); if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all); ret = ret.run(to[x] -> my); printf("%d\n", ret.maxx); } else if (tp == 5) { int x, y; in(x); in(y); to[x] -> access(); to[x] -> splayO(); if (x == rt) { to[x] -> push_tag_chain(Tag(1, y)); to[x] -> push_tag_sub(Tag(1, y)); } else { to[x] -> my = to[x] -> my.run(Tag(1, y)); if (to[x] -> ch[2] != NULL) { to[x] -> ch[2] -> push_tag_chain(Tag(1, y)); to[x] -> ch[2] -> push_tag_sub(Tag(1, y)); } if (to[x] -> ch[3] != NULL) { to[x] -> ch[3] -> push_tag_chain(Tag(1, y)); to[x] -> ch[3] -> push_tag_sub(Tag(1, y)); } to[x] -> update(); } } else if (tp == 6) { int x, y, z; in(x); in(y); in(z); to[x] -> makerot(); to[y] -> access(); to[y] -> splayO(); to[y] -> push_tag_chain(Tag(1, z)); } else if (tp == 7) { int x, y; in(x); in(y); to[x] -> makerot(); to[y] -> access(); to[y] -> splayO(); printf("%d\n", to[y] -> my.run(to[y] -> data_chain).minx); } else if (tp == 8) { int x, y; in(x); in(y); to[x] -> makerot(); to[y] -> access(); to[y] -> splayO(); printf("%d\n", to[y] -> my.run(to[y] -> data_chain).maxx); } else if (tp == 9) { int x, y; in(x); in(y); to[y] -> access(); to[x] -> access(); to[x] -> splayO(); to[x] -> pushdown(); if (to[x] -> ch[0] == NULL) continue; else { to[y] -> access(); to[y] -> splayO(); Node *tmp = to[x]; while (!tmp -> is_top_out()) tmp = tmp -> fa; if (tmp == to[y]) continue; to[x] -> access(); to[x] -> splayO(); to[x] -> pushdown(); tmp = to[x] -> ch[0]; tmp -> pushdown(); while (tmp -> ch[1] != NULL) {tmp = tmp -> ch[1]; tmp -> pushdown();} cut(to[x], tmp); link(to[x], to[y]); } } else if (tp == 10) { int x, y; in(x); in(y); to[x] -> makerot(); to[y] -> access(); to[y] -> splayO(); printf("%d\n", to[y] -> my.run(to[y] -> data_chain).sum); } else if (tp == 11) { int x; in(x); to[x] -> access(); //to[x] -> splayO(); Data ret = Data(); if (to[x] -> ch[2] != NULL) ret = ret.run(to[x] -> ch[2] -> data_all); if (to[x] -> ch[3] != NULL) ret = ret.run(to[x] -> ch[3] -> data_all); ret = ret.run(to[x] -> my); printf("%d\n", ret.sum); } } return 0;}
阅读全文
2 0
- [bzoj3153] sone1 AC纪念
- 【(伪)Top tree】【BZOJ3153 Sone1 题解】
- 【纪念篇】 洛谷AC 100 纪念
- ACM ZOJ AC 100 总结纪念
- 第一题java AC纪念一下~
- 很长时间 第一次自己写代码ac 纪念一下
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念
- 纪念。。。
- 1526:宗教信仰(4.3算法之图论)
- JavaScript趣味编程--仿微信飞机大战游戏--1.画飞机
- 蔡勒公式计算星期+枚举
- 第一个Java Web项目
- python,格式化字符串函数.format()的用法
- [bzoj3153] sone1 AC纪念
- internet时间同步服务器地址(中国国家授时中心)
- 【项目经验】C语言中inline的深入理解
- 解决安装MindManager后鼠标失灵问题
- Perceptron(一)
- linux下修改mysql的root账号的密码
- dp基础10 -- H
- 2017百度之星初赛(A) 1001 小C的倍数问题(基础数论)
- POJ 2657 Comfort