再搬运:

关于树剖的具体内容上,传送门:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html(非常之详细)

链剖完,线段树上维护的是段最大以及段和即可,操作是点修改。

但是要注意有负数的情况!!!蒟蒻没看到WA了7、8次。。。蒟蒻就是弱,树剖竟然要写三天。。。买块豆腐去撞死吧

时间竟然有2500+MS,不过把许多大神踩在下面了,感觉挺好。。

上代码,感觉写的还不错啊,思路蛮清晰的:

 

  1 #include <cstdlib>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7  
  8 #define rep(i, n) for (int (i) = 1; (i) <= (n); ++(i))
  9 using namespace std;
 10  
 11 struct edge{
 12     int next, to;
 13 } e[100000];
 14  
 15 struct tree{
 16     int fa, son, size, w, dep, top, where;
 17 } tr[100000];
 18  
 19 struct segment_tree{
 20     int sum, max;
 21 } seg[100000];
 22  
 23 int n, tot, first[100000], size, t, lx, ry;
 24  
 25 void add_Edge(int x, int y){
 26     e[++tot].next = first[x];
 27     first[x] = tot;
 28     e[tot].to = y;
 29 }
 30  
 31 void add_edge(int x, int y){
 32     add_Edge(x, y);
 33     add_Edge(y, x);
 34 }
 35  
 36 void make_tree(int p){
 37     int y;
 38     tr[p].size = 1;
 39     tr[p].son = 0;
 40     for (int x = first[p]; x != 0; x = e[x].next){
 41         y = e[x].to;
 42         if (y != tr[p].fa){
 43             tr[y].dep = tr[p].dep + 1;
 44             tr[y].fa = p;
 45             make_tree(y);
 46             if (tr[p].son == 0 || tr[y].size > tr[tr[p].son].size)
 47                 tr[p].son = y;
 48             tr[p].size += tr[y].size;
 49         }
 50     }
 51 }
 52  
 53 void fill_seg(int i){
 54     if (i >= size){
 55         seg[i].max = -30001;
 56         seg[i].sum = -30001;
 57         return;
 58     }
 59     fill_seg(i * 2);
 60     fill_seg(i * 2 + 1);
 61     seg[i].max = -30001;
 62     seg[i].sum = seg[i * 2].sum * 2;
 63 }
 64  
 65 void change_value(int p, int v){
 66     int x = tr[p].where + size;
 67     seg[x].max = v;
 68     seg[x].sum = v;
 69     while (x > 1){
 70         x >>= 1;
 71         seg[x].max = max(seg[x * 2].max, seg[x * 2 + 1].max);
 72         seg[x].sum = seg[x * 2].sum + seg[x * 2 + 1].sum;
 73     }  
 74 }
 75  
 76 void build_seg(int p){
 77     tr[p].where = ++t;
 78     change_value(p, tr[p].w);
 79 }
 80  
 81 void make_seg(int p){
 82     if (tr[p].size == 1) return;
 83     int s = tr[p].son, y;
 84     tr[s].top = tr[p].top;
 85     build_seg(s);
 86     make_seg(s);
 87     for (int x = first[p]; x != 0; x = e[x].next)
 88         if ((y = e[x].to) != tr[p].fa && y != tr[p].son){
 89             tr[y].top = y;
 90             build_seg(y);
 91             make_seg(y);
 92         }
 93 }
 94  
 95 int seg_max(int p, int l, int r){
 96     if (r < lx || l > ry) return -30001;
 97     if (lx <= l && r <= ry) return seg[p].max;
 98     int m = (l + r) >> 1;
 99     int t1 = seg_max(p * 2, l, m), t2 = seg_max(p * 2 + 1, m + 1, r);
100     return max(t1, t2);
101 }
102  
103 int tree_max(int x, int y){
104     if (tr[x].top == tr[y].top){
105         if (tr[x].dep > tr[y].dep) swap(x, y);
106         lx = tr[x].where;
107         ry = tr[y].where;
108         return seg_max(1, 1, size + 1);
109     }
110     if (tr[tr[x].top].dep < tr[tr[y].top].dep) swap(x, y);
111     lx = tr[tr[x].top].where;
112     ry = tr[x].where;
113     int t1 = seg_max(1, 1, size + 1), t2 = tree_max(tr[tr[x].top].fa, y);
114     return max(t1, t2);
115 }
116  
117 int seg_sum(int p, int l, int r){
118     if (r < lx || l > ry) return 0;
119     if (lx <= l && r <= ry) return seg[p].sum;
120     int m = (l + r) >> 1;
121     int t1 = seg_sum(p * 2, l, m), t2 = seg_sum(p * 2 + 1, m + 1, r);
122     return t1 + t2;
123 }
124  
125 int tree_sum(int x, int y){
126     if (tr[x].top == tr[y].top){
127         if (tr[x].dep > tr[y].dep) swap(x, y);
128         lx = tr[x].where;
129         ry = tr[y].where;
130         return seg_sum(1, 1, size + 1);
131     }
132     if (tr[tr[x].top].dep < tr[tr[y].top].dep) swap(x, y);
133     lx = tr[tr[x].top].where;
134     ry = tr[x].where;
135     int t1 = seg_sum(1, 1, size + 1) , t2 = tree_sum(tr[tr[x].top].fa, y);
136     return t1 + t2;
137 }
138  
139 int main(){
140     scanf("%d", &n);
141     int x, y;
142     rep(i, n - 1){
143         scanf("%d %d", &x, &y);
144         add_edge(x, y);
145     }
146     rep(i, n)
147         scanf("%d", &tr[i].w);
148  
149     for (size = 1; size < n; size <<= 1);
150     --size;
151  
152     tr[1].dep = 1;
153     make_tree(1);
154     tr[1].top = 1;
155     t = 0;
156     fill_seg(1);
157     build_seg(1);
158     make_seg(1);
159  
160     int q, a;      
161     scanf("%d", &q);
162     char C[10];
163     while (q--){
164         scanf("%s %d %d", C, &x, &y);
165         if (C[0] == 'C')
166             change_value(x, y); else
167         if (C[1] == 'M')
168             printf("%d\n", tree_max(x, y)); else
169         if (C[1] == 'S')
170             printf("%d\n", tree_sum(x, y));
171     }
172     return 0;
173 }
View Code

 

posted on 2014-10-10 22:54  Xs酱~  阅读(172)  评论(0编辑  收藏  举报