[BZOJ1036][ZJOI2008]树的统计Count && LCT

来源:互联网 发布:淘宝店代管理 编辑:程序博客网 时间:2024/04/18 18:31

这道题怎么看怎样像树链剖分 然而 LCT这么好用的东西真的是不用白不用了啊 直接搞就是了

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>#include<map>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 30000;struct LCT {int ch[MAXN+10][2], fa[MAXN+10];int val[MAXN+10], st[MAXN+10];int sum[MAXN+10], MAX[MAXN+10];bool rev[MAXN+10];bool isroot(int x) {return ch[fa[x]][0] != x && ch[fa[x]][1] != x;}void up(int x) {int ls = ch[x][0], rs = ch[x][1];sum[x] = sum[ls] + sum[rs] + val[x];MAX[x] = max(val[x], max(MAX[ls], MAX[rs]));}void pushdown(int x) {int &ls = ch[x][0], &rs = ch[x][1];if(rev[x]) {rev[x] ^= 1; rev[ls] ^= 1; rev[rs] ^= 1;swap(ls, rs);}}void Rotate(int x) {int y = fa[x], z = fa[y];bool d = x == ch[y][0];if(!isroot(y)) ch[z][y == ch[z][1]] = x;fa[x] = z; fa[y] = x; fa[ch[x][d]] = y;ch[y][!d] = ch[x][d]; ch[x][d] = y;up(y);}void splay(int x) {int top = 0; st[++top] = x;for(int i = x; !isroot(i); i = fa[i]) st[++top] = fa[i];for(int i = top; i; i--) pushdown(st[i]);while(!isroot(x)) {int y = fa[x], z = fa[y];if(!isroot(y)) Rotate((x == ch[y][0] ^ y == ch[z][0]) ? x : y);Rotate(x);}up(x);}void access(int x) {int t = 0;while(x) {splay(x);ch[x][1] = t;up(x);t = x; x = fa[x];}}void makeroot(int x) {access(x); splay(x); rev[x] ^= 1;}void change(int x, int y) {access(x); splay(x); val[x] = y; up(x);}int query_max(int x, int y) {makeroot(x); access(y); splay(y);return MAX[y];}int query_sum(int x, int y) {makeroot(x); access(y); splay(y);return sum[y];}} sp;int n, m;struct Node {int v, next;} Edge[MAXN*2+10];int adj[MAXN+10], ecnt;void add(int u, int v) {Node &e = Edge[ecnt];e.v = v; e.next = adj[u]; adj[u] = ecnt++;}void dfs(int u) {for(int i = adj[u]; ~i; i = Edge[i].next) {int v = Edge[i].v;if(sp.fa[u] == v) continue;sp.fa[v] = u;dfs(v);}}int main() {memset(adj, -1, sizeof(adj));sp.MAX[0] = -1234567890;char s[10];SF("%d", &n);for(int i = 1; i < n; i++) {int u, v; SF("%d%d", &u, &v);add(u, v); add(v, u);}dfs(1);for(int i = 1; i <= n; i++) {int x; SF("%d", &x);sp.val[i] = sp.sum[i] = sp.MAX[i] = x;}SF("%d", &m);for(int i = 1; i <= m; i++) {int x, y;SF("%s%d%d", s, &x, &y);if(s[0] == 'Q') {if(s[1] == 'M') PF("%d\n", sp.query_max(x, y));else PF("%d\n", sp.query_sum(x, y));}else sp.change(x, y);}}


0 0
原创粉丝点击