标签:
1.题目描述:点击打开链接
2.解题思路:LCT的模板题
3.代码:
#include <cstdio> #include <cstdlib> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int N = 111111; const int INF = 1111111111; int n, m; class LCT { private : struct node { int size, same, rev, val, inc; pair<int, int> value[2]; node *child[2], *father; bool isRoot; inline void setChild(node *tmp, int dir) { child[dir] = tmp; tmp->father = this; } inline int isRc() { return father->child[1] == this; } int calc(int v) { int res = 0; if (val == v) { res++; } for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) { if (this->child[i]->value[j].first == v) { res += this->child[i]->value[j].second; } } return res; } inline void update() { if (size == 0) { return ; } int maxValue = max(val, max(child[0]->value[0].first, child[1]->value[0].first)); value[0] = make_pair(maxValue, this->calc(maxValue)); int sec = -INF; if (val != maxValue) { sec = max(sec, val); } for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) { if (this->child[i]->value[j].first != maxValue) { sec = max(sec, this->child[i]->value[j].first); } } value[1] = make_pair(sec, this->calc(sec)); size = 1 + child[0]->size + child[1]->size; } inline void make(int v) { if (size == 0) { return ; } value[0] = make_pair(v, size); value[1] = make_pair(-INF, 0); same = v; inc = 0; val = v; } inline void add(int v) { if (size == 0) { return ; } inc += v; val += v; if (value[0].first != -INF) { value[0].first += v; } if (value[1].first != -INF) { value[1].first += v; } } inline void reverse() { if (size == 0) { return ; } rev ^= 1; swap(child[0], child[1]); } inline void push() { if (size == 0) { return ; } if (rev) { child[0]->reverse(); child[1]->reverse(); rev = 0; } if (same != -INF) { child[0]->make(same); child[1]->make(same); same = -INF; } if (inc) { child[0]->add(inc); child[1]->add(inc); inc = 0; } } }; typedef node *Node; node mem[N]; int used; Node Null, t[N]; Node newNode(int v) { Node temp = &mem[used++]; temp->size = 1, temp->same = -INF, temp->rev = 0, temp->val = v, temp->inc = 0; temp->value[0] = make_pair(v, 1); temp->value[1] = make_pair(-INF, 0); temp->child[0] = temp->child[1] = temp->father = Null; temp->isRoot = true; return temp; } void rotate(Node root) { Node father = root->father; father->push(); root->push(); int dir = root->isRc(); father->setChild(root->child[!dir], dir); if (father->isRoot) { father->isRoot = false; root->isRoot = true; root->father = father->father; } else { father->father->setChild(root, father->isRc()); } root->setChild(father, !dir); father->update(); } void splay(Node root) { for(root->push(); !root->isRoot; ) { if (root->father->isRoot) { rotate(root); } else { (root->isRc() == root->father->isRc()) ? (rotate(root->father), rotate(root)) : (rotate(root), rotate(root)); } } root->update(); } void access(Node root, int oper = 0, int val = 0) { for(Node tmp(Null); root != Null; ) { splay(root); if (root->father == Null && oper) { if (oper == 1) { tmp->make(val); root->push(); root->child[1]->make(val); root->val = val; root->update(); } else if (oper == 2) { tmp->add(val); root->push(); root->child[1]->add(val); root->val += val; root->update(); } } root->child[1]->isRoot = true; root->child[1] = tmp; root->child[1]->isRoot = false; root->update(); tmp = root; root = root->father; } } public: void init(int n, int val[]) { used = 0; Null = newNode(-INF); Null->father = Null->child[0] = Null->child[1] = Null; Null->size = 0; for(int i = 1; i <= n; i++) { t[i] = newNode(val[i]); } } void Link(int son, int father) { access(t[son]); splay(t[son]); t[son]->father = t[father]; t[son]->reverse(); } void Cut(int u, int v) { access(t[v]); splay(t[u]); if (t[u]->father == t[v]) { t[u]->father = Null; } else { access(t[u]); splay(t[v]); if (t[v]->father == t[u]) { t[v]->father = Null; } } } void makeSame(int u, int v, int val) { access(t[u]); access(t[v], 1, val); } void add(int u, int v, int val) { access(t[u]); access(t[v], 2, val); } pair<int, int> getValue(int u, int v) { access(t[u]); Node root = t[v]; pair<int, int> res; for(Node tmp(Null); root != Null; ) { splay(root); if (root->father == Null) { root->push(); Node a = tmp, b = root->child[1]; vector<int> vv; vv.push_back(root->val); for(int i = 0; i < 2; i++) { vv.push_back(a->value[i].first); vv.push_back(b->value[i].first); } sort(vv.begin(), vv.end()); vv.erase(unique(vv.begin(), vv.end()), vv.end()); reverse(vv.begin(), vv.end()); while(vv.size() && vv.back() == -INF) { vv.pop_back(); } if (vv.size() == 1) { res = make_pair(-INF, 0); } else { res = make_pair(vv[1], 0); for(int i = 0; i < 2; i++) { if (a->value[i].first == vv[1]) { res.second += a->value[i].second; } if (b->value[i].first == vv[1]) { res.second += b->value[i].second; } } res.second += (root->val == vv[1]); } } root->child[1]->isRoot = true; root->child[1] = tmp; root->child[1]->isRoot = false; root->update(); tmp = root; root = root->father; } return res; } }tree; int main() { int test; scanf("%d", &test); while(test--) { static int testCount = 0; printf("Case #%d:\n", ++testCount); scanf("%d %d", &n, &m); static int val[N]; for(int i = 1; i <= n; i++) { scanf("%d", &val[i]); } tree.init(n, val); for(int i = 1; i < n; i++) { int a, b; scanf("%d %d", &a, &b); tree.Link(a, b); } for(int i = 1; i <= m; i++) { int type, a, b, x, y; scanf("%d", &type); if (type == 1) { scanf("%d %d %d %d", &x, &y, &a, &b); tree.Cut(x, y); tree.Link(a, b); } else if (type == 2) { scanf("%d %d %d", &a, &b, &x); tree.makeSame(a, b, x); } else if (type == 3) { scanf("%d %d %d", &a, &b, &x); tree.add(a, b, x); } else { int a, b; scanf("%d %d", &a, &b); pair<int, int> temp = tree.getValue(a, b); if (temp.first == -INF) { printf("ALL SAME\n"); } else { printf("%d %d\n", temp.first, temp.second); } } } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 5002 Tree (2014年鞍山赛区网络赛F题)
标签:
原文地址:http://blog.csdn.net/u014800748/article/details/48041475