bzoj 1036 [LCT version] 分类: templates bzoj 2015-08-06 22:05 20人阅读 评论(0) 收藏
2015-08-06 22:05
417 查看
LCT。单个操作时间复杂度O(logN),然而常数巨大。
杨哲《QTREE解法的一些研究》
黄志翱《浅谈动态树的相关问题及简单拓展》
杨哲《QTREE解法的一些研究》
黄志翱《浅谈动态树的相关问题及简单拓展》
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <string> #include <map> #include <vector> #include <stack> #include <queue> #include <utility> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]); } const int maxn = 1e5 + 5, INF = 0x3f3f3f3f; struct TreeNode { int c[2], fa, rev, max, sum; }S[maxn]; int n, m, pf[maxn], w[maxn]; #define check(x) x namespace Data { void Update(int x) { S[x].max = std::max(std::max(S[S[x].c[0]].max, S[S[x].c[1]].max), w[x]); S[x].sum = S[S[x].c[0]].sum + S[S[x].c[1]].sum + w[x]; } void PushDown(int x) { if(x && S[x].rev) { std::swap(S[x].c[0], S[x].c[1]); S[S[x].c[0]].rev ^= 1; S[S[x].c[1]].rev ^= 1; S[x].rev = 0; } } void Rotate(int x) { int y, z, i, j; y = S[x].fa, z = S[y].fa; j = (S[z].c[1] == y), PushDown(y); i = (S[y].c[1] == x), PushDown(x); if(check(z)) S[z].c[j] = x; else pf[x] = pf[y], pf[y] = 0; if(S[x].c[i^1]) S[S[x].c[i^1]].fa = y; S[x].fa = z, S[y].fa = x; S[y].c[i] = S[x].c[i^1], S[x].c[i^1] = y; Update(y), Update(x); } void Splay(int v) { int g = S[v].fa, h = S[g].fa; PushDown(v); while(check(g)) { if(check(h)) { if((S[h].c[1] == g)^(S[g].c[1] == v)) Rotate(v); else Rotate(g); } Rotate(v), g = S[v].fa, h = S[g].fa; } Update(v); } } namespace LCT { void Access(int v) { int u = v, e = v; v = 0; while(u) { Data::Splay(u); int &t = S[u].c[1]; if(check(t)) pf[t] = u, S[t].fa = 0; if(check(v)) pf[v] = 0, S[v].fa = u; t = v, Data::Update(u); v = u, u = pf[u]; } Data::Splay(e); } void MakeRoot(int v) { Access(v); S[v].rev ^= 1; } void Join(int v,int u) { MakeRoot(v); pf[v] = u; Access(v); } int Query(int u,int v) { MakeRoot(u); Access(v); return v; } } #undef check struct StarEdge { int u, v; void scan() { read(u), read(v); } void connect() { LCT::Join(v, u); } }edge[maxn]; void init() { read(n); for(int i = 1; i < n; i++) edge[i].scan(); for(int i = 1; i <= n; i++) read(w[i]); } void solve() { char str[10]; int x, y; for(int i = 1; i <= n; i++) S[i].max = S[i].sum = w[i]; S[0].max = -INF; for(int i = 1; i < n; i++) edge[i].connect(); read(m); while(m--) { scanf("%s", str); read(x), read(y); switch(str[1]) { case 'H': LCT::Access(x), w[x] = y, Data::Update(x); break; case 'S': write(S[LCT::Query(x, y)].sum), puts(""); break; case 'M': write(S[LCT::Query(x, y)].max), puts(""); break; } } } int main() { #ifndef ONLINE_JUDGE freopen("1036.in","r",stdin); freopen("1036.out","w",stdout); #endif init(); solve(); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- @font-face的format属性
- 使用Maven来管理项目(一) Maven的安装与配置
- LeetCode #215 Kth Largest Element in an Array
- 《将51CTO博客搬至CSDN》
- hdu 5363 快速幂取模
- mysql 高可用7
- avalon与双缓冲技术
- 用CountDownTimer实现获取手机验证码效果
- 集线器(Hub)、网线、网卡、交换机、路由器分别工作在OSI参考模型的哪一层?
- C#中的泛型介绍和理解
- 同构字符串
- HDU - 1711 Number Sequence KMP字符串匹配
- 关于Java单例
- leetcode_Median of Two Sorted Arrays
- Puzzler: Nested computeIfAbsent -Java 8
- iOS 动画总结----UIView动画
- 第四章 初步进入linux世界
- ios代理的使用,正向传值,逆向传值
- CodeForces 567C. Geometric Progression(map 数学啊)
- 添加本地路由表项