标签:ios memset inf tps cstring void namespace sub 记录
第一遍树链剖分,打的很难受。
其中拉闸了,检查真是费劲。
详解什么的就不给了。(其实我现在也看不懂)
看模板的专题吧。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define rt 1, 1, n 5 #define ls o << 1, l, m 6 #define rs o << 1 | 1, m + 1, r 7 8 using namespace std; 9 10 const int maxn = 300001; 11 const int INF = 99999999; 12 int n, m, q, cnt, tim; 13 int a[maxn], head[maxn], to[maxn << 2], next[maxn << 2], deep[maxn], size[maxn]; 14 int son[maxn], top[maxn], f[maxn], tid[maxn], rank[maxn], sumv[maxn], maxv[maxn]; 15 //a节点权值, deep节点深度, size以x为根的子树节点个数, son重儿子, top当前节点所在链的顶端节点 16 //f当前节点父亲, tid保存树中每个节点剖分后的新编号, rank保存当前节点在线段树中的位置 17 18 void add(int x, int y) 19 { 20 to[cnt] = y; 21 next[cnt] = head[x]; 22 head[x] = cnt++; 23 } 24 25 void dfs1(int u, int father)//记录所有重边 26 { 27 int i, v; 28 size[u] = 1; 29 for(i = head[u]; i != -1; i = next[i]) 30 { 31 v = to[i]; 32 if(v == father) continue; 33 deep[v] = deep[u] + 1; 34 f[v] = u; 35 dfs1(v, u); 36 size[u] += size[v]; 37 if(son[u] == -1 || size[v] > size[son[u]]) son[u] = v; 38 } 39 } 40 41 void dfs2(int u, int tp) 42 { 43 int i, v; 44 top[u] = tp; 45 tid[u] = ++tim; 46 rank[tim] = u; 47 if(son[u] == -1) return; 48 dfs2(son[u], tp);//重边 49 for(i = head[u]; i != -1; i = next[i]) 50 { 51 v = to[i]; 52 if(v != son[u] && v != f[u]) dfs2(v, v);//轻边 53 } 54 } 55 56 void pushup(int o) 57 { 58 sumv[o] = sumv[o << 1] + sumv[o << 1 | 1]; 59 maxv[o] = max(maxv[o << 1], maxv[o << 1 | 1]); 60 } 61 62 void updata(int o, int l, int r, int d, int x) 63 { 64 int m = (l + r) >> 1; 65 if(l == r) 66 { 67 sumv[o] = maxv[o] = x; 68 return; 69 } 70 if(d <= m) updata(ls, d, x); 71 else updata(rs, d, x); 72 pushup(o); 73 } 74 75 void build(int o, int l, int r) 76 { 77 int m = (l + r) >> 1; 78 if(l == r) 79 { 80 sumv[o] = maxv[o] = a[rank[l]]; 81 return; 82 } 83 build(ls); 84 build(rs); 85 pushup(o); 86 } 87 88 int querymax(int o, int l, int r, int ql, int qr) 89 { 90 int m = (l + r) >> 1, ans = -INF; 91 if(ql <= l && r <= qr) return maxv[o]; 92 if(ql <= m) ans = max(ans, querymax(ls, ql, qr)); 93 if(m < qr) ans = max(ans, querymax(rs, ql, qr)); 94 pushup(o); 95 return ans; 96 } 97 98 int qmax(int u, int v) 99 { 100 int ans = -INF; 101 while(top[u] != top[v]) 102 { 103 if(deep[top[u]] < deep[top[v]]) swap(u, v); 104 ans = max(ans, querymax(rt, tid[top[u]], tid[u])); 105 u = f[top[u]]; 106 } 107 if(deep[u] < deep[v]) swap(u, v); 108 ans = max(ans, querymax(rt, tid[v], tid[u])); 109 return ans; 110 } 111 112 int querysum(int o, int l, int r, int ql, int qr) 113 { 114 int m = (l + r) >> 1, ans = 0; 115 if(ql <= l && r <= qr) return sumv[o]; 116 if(ql <= m) ans += querysum(ls, ql, qr); 117 if(m < qr) ans += querysum(rs, ql, qr); 118 pushup(o); 119 return ans; 120 } 121 122 int qsum(int u, int v) 123 { 124 int ans = 0; 125 while(top[u] != top[v]) 126 { 127 if(deep[top[u]] < deep[top[v]]) swap(u, v); 128 ans += querysum(rt, tid[top[u]], tid[u]); 129 u = f[top[u]]; 130 } 131 if(deep[u] < deep[v]) swap(u, v); 132 ans += querysum(rt, tid[v], tid[u]); 133 return ans; 134 } 135 136 int main() 137 { 138 int i, j, x, y; 139 char s[11]; 140 memset(head, -1, sizeof(head)); 141 memset(son, -1, sizeof(son)); 142 scanf("%d", &n); 143 for(i = 1; i < n; i++) 144 { 145 scanf("%d %d", &x, &y); 146 add(x, y); 147 add(y, x); 148 } 149 for(i = 1; i <= n; i++) scanf("%d", &a[i]); 150 deep[1] = 1; 151 f[1] = 1; 152 dfs1(1, -1); 153 dfs2(1, 1); 154 build(rt); 155 scanf("%d", &q); 156 for(i = 1; i <= q; i++) 157 { 158 scanf("%s %d %d", s, &x, &y); 159 if(s[1] == ‘H‘) updata(rt, tid[x], y); 160 if(s[1] == ‘M‘) printf("%d\n", qmax(x, y)); 161 if(s[1] == ‘S‘) printf("%d\n", qsum(x, y)); 162 } 163 return 0; 164 }
标签:ios memset inf tps cstring void namespace sub 记录
原文地址:http://www.cnblogs.com/zhenghaotian/p/6705918.html