SPOJ……无力吐槽了,反正RP好的时候过了,其他时候都是TLE。
只能怪自己动态树太龊了吧。。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<iostream> 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 #define oo 0x7FFFFFFF 7 #define MAXN 200010 8 using namespace std; 9 bool vis[MAXN]; 10 int e, first[MAXN], next[MAXN], v[MAXN]; 11 struct LCT { 12 int bef[MAXN]; 13 int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN]; 14 int left[MAXN], right[MAXN], sum[MAXN], val[MAXN], same[MAXN]; 15 inline void PushUp(int x) { 16 int L, R; 17 L = next[x][0], R = next[x][1]; 18 num[x] = num[L] + num[R] + 1; 19 sum[x] = sum[L] + sum[R] + key[x]; 20 left[x] = MAX(left[L],sum[L]+key[x]+left[R]); 21 right[x] = MAX(right[R],sum[R]+key[x]+right[L]); 22 val[x] = MAX(val[L],val[R]); 23 val[x] = MAX(val[x],key[x]+right[L]+left[R]); 24 } 25 inline void Down(int x, int k) { 26 if (x) { 27 same[x] = key[x] = k; 28 sum[x] = k * num[x]; 29 left[x] = right[x] = val[x] = MAX(sum[x],0); 30 } 31 } 32 inline void PushDown(int x) { 33 if (same[x] != oo) { 34 int L, R; 35 L = next[x][0], R = next[x][1]; 36 if (L) { 37 same[L] = key[L] = same[x]; 38 sum[L] = same[x] * num[L]; 39 left[L] = right[L] = val[L] = MAX(sum[L],0); 40 } 41 if (R) { 42 same[R] = key[R] = same[x]; 43 sum[R] = same[x] * num[R]; 44 left[R] = right[R] = val[R] = MAX(sum[R],0); 45 } 46 same[x] = oo; 47 } 48 } 49 void Rotate(int x, int kind) { 50 int y, z; 51 y = pre[x]; 52 z = pre[y]; 53 PushDown(y); 54 PushDown(x); 55 next[y][!kind] = next[x][kind]; 56 pre[next[x][kind]] = y; 57 next[z][next[z][1] == y] = x; 58 pre[x] = z; 59 next[x][kind] = y; 60 pre[y] = x; 61 PushUp(y); 62 } 63 void Splay(int x) { 64 int rt; 65 for (rt = x; pre[rt]; rt = pre[rt]) 66 ; 67 if (rt != x) { 68 bef[x] = bef[rt]; 69 bef[rt] = 0; 70 while (pre[x]) { 71 if (next[pre[x]][0] == x) 72 Rotate(x, 1); 73 else 74 Rotate(x, 0); 75 } 76 PushUp(x); 77 } else 78 PushDown(x); 79 } 80 void Access(int x) { 81 int father; 82 for (father = 0; x; x = bef[x]) { 83 Splay(x); 84 bef[next[x][1]] = x; 85 pre[next[x][1]] = 0; 86 next[x][1] = father; 87 pre[father] = x; 88 bef[father] = 0; 89 father = x; 90 PushUp(x); 91 } 92 } 93 int Query(int x, int y) { 94 int ans; 95 Access(y); 96 for (y = 0; x; x = bef[x]) { 97 Splay(x); 98 if (!bef[x]) { 99 ans = MAX(val[y],val[next[x][1]]); 100 ans = MAX(ans,key[x]+left[y]+left[next[x][1]]); 101 return ans; 102 } 103 bef[next[x][1]] = x; 104 pre[next[x][1]] = 0; 105 next[x][1] = y; 106 pre[y] = x; 107 bef[y] = 0; 108 y = x; 109 PushUp(x); 110 } 111 return 0; 112 } 113 void Update(int x, int y, int price) { 114 Access(y); 115 for (y = 0; x; x = bef[x]) { 116 Splay(x); 117 if (!bef[x]) { 118 key[x] = price; 119 if (y) { 120 same[y] = key[y] = price; 121 sum[y] = price * num[y]; 122 left[y] = right[y] = val[y] = MAX(price,0); 123 } 124 if (next[x][1]) { 125 y = next[x][1]; 126 same[y] = key[y] = price; 127 sum[y] = price * num[y]; 128 left[y] = right[y] = val[y] = MAX(price,0); 129 } 130 } 131 bef[next[x][1]] = x; 132 pre[next[x][1]] = 0; 133 next[x][1] = y; 134 pre[y] = x; 135 bef[y] = 0; 136 y = x; 137 PushUp(x); 138 } 139 } 140 } lct; 141 inline void AddEdge(int x, int y) { 142 v[e] = y; 143 next[e] = first[x]; 144 first[x] = e++; 145 } 146 void BFS(int x) { 147 int i, y; 148 queue<int> q; 149 vis[x] = true; 150 q.push(x); 151 while (!q.empty()) { 152 x = q.front(); 153 q.pop(); 154 for (i = first[x]; i != -1; i = next[i]) { 155 y = v[i]; 156 if (!vis[y]) { 157 lct.same[y] = oo; 158 lct.bef[y] = x; 159 vis[y] = true; 160 q.push(y); 161 } 162 } 163 } 164 } 165 int INT() { 166 int res; 167 char ch; 168 bool neg; 169 while (ch = getchar_unlocked(), !isdigit(ch) && ch != '-') 170 ; 171 if (ch == '-') { 172 res = 0; 173 neg = true; 174 } else { 175 res = ch - '0'; 176 neg = false; 177 } 178 while (ch = getchar_unlocked(), isdigit(ch)) 179 res = res * 10 + ch - '0'; 180 return neg ? -res : res; 181 } 182 int main() { 183 int n, i, q, cmd, x, y, val; 184 n = INT(); 185 for (i = 1; i <= n; i++) { 186 lct.key[i] = INT(); 187 lct.same[i] = oo; 188 } 189 memset(first, -1, sizeof(first)); 190 for (e = 0, i = 1; i < n; i++) { 191 x = INT(), y = INT(); 192 AddEdge(x, y); 193 AddEdge(y, x); 194 } 195 BFS(1); 196 scanf("%d", &q); 197 while (q--) { 198 cmd = INT(), x = INT(), y = INT(); 199 if (cmd == 1) 200 printf("%d\n", lct.Query(x, y)); 201 else { 202 val = INT(); 203 lct.Update(x, y, val); 204 } 205 } 206 return 0; 207 }