易知,答案就是各个关键点之间形成的树的边权和的两倍,哦。。就是虚树

对于一颗虚树,答案就是各个的dfs序排序,相邻两点的距离和,再加上最后一个到第一个的距离

直接用set维护dfs序就好了

注意最后要剪掉所有关键点的LCA的深度

 

  1 /**************************************************************
  2     Problem: 3991
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:7304 ms
  7     Memory:42584 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12 #include <set>
 13  
 14 using namespace std;
 15 const int N = 1e5 + 5;
 16 typedef long long ll;
 17 typedef set<int> :: iterator iter;
 18  
 19 struct edge {
 20     int next, to, v;
 21     edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {}
 22 } e[N << 1];
 23  
 24 struct tree_node {
 25     int fa, w, now;
 26     ll dis;
 27 } tr[N];
 28  
 29 int n, m;
 30 int first[N], tot;
 31 int lg2[N << 1], cnt_seq;
 32 ll ans, st[N << 1][20];
 33 set<int> seq;
 34  
 35 inline int read();
 36  
 37 inline void Add_Edges(int x, int y, int z) {
 38     e[++tot] = edge(first[x], y, z), first[x] = tot;
 39     e[++tot] = edge(first[y], x, z), first[y] = tot;
 40 }
 41  
 42 #define y e[x].to
 43 void dfs(int p) {
 44     int x;
 45     st[tr[p].w = ++cnt_seq][0] = tr[p].dis;
 46     for (x = first[p]; x; x = e[x].next)
 47         if (y != tr[p].fa) {
 48             tr[y].fa = p, tr[y].dis = tr[p].dis + e[x].v;
 49             dfs(y);
 50             st[++cnt_seq][0] = tr[p].dis;
 51         }
 52 }
 53 #undef y
 54  
 55 ll query(int x, int y) {
 56     static int t;
 57     t = lg2[y - x + 1];
 58     return min(st[x][t], st[y - (1 << t) + 1][t]);
 59 }
 60  
 61 template <class T> inline T nxt(const T &it) {
 62     static T tmp;
 63     tmp = it;
 64     return ++tmp;
 65 }
 66  
 67 template <class T> inline T pre(const T &it) {
 68     static T tmp;
 69     tmp = it;
 70     return --tmp;
 71 }
 72  
 73 inline void insert(int p) {
 74     static iter it;
 75     it = seq.insert(p).first;
 76     ans += st[p][0];
 77     if (seq.size() == 1) return;
 78     if (it == seq.begin()) {
 79         ans -= query(*it, *nxt(it));
 80         return;
 81     }
 82     if (nxt(it) == seq.end()) {
 83         ans -= query(*pre(it), *it);
 84         return;
 85     }
 86     ans += query(*pre(it), *nxt(it)) - query(*pre(it), *it) - query(*it, *nxt(it));
 87 }
 88  
 89 inline void erase(int p) {
 90     static iter it;
 91     it = seq.find(p);
 92     ans -= st[p][0];
 93     if (seq.size() == 1) {
 94         seq.erase(it);
 95         return;
 96     }
 97     if (it == seq.begin()) {
 98         ans += query(*it, *nxt(it));
 99         seq.erase(it);
100         return;
101     }
102     if (nxt(it) == seq.end()) {
103         ans += query(*pre(it), *it);
104         seq.erase(it);
105         return;     
106     }
107     ans -= query(*pre(it), *nxt(it)) - query(*pre(it), *it) - query(*it, *nxt(it));
108     seq.erase(it);
109 }
110  
111 ll LCA() {
112     if (seq.size() == 0) return 0ll;
113     return query(*seq.begin(), *pre(seq.end()));
114 }
115  
116 int main() {
117     int i, j, x, y, z;
118     n = read(), m = read();
119     for (i = 1; i < n; ++i) {
120         x = read(), y = read(), z = read();
121         Add_Edges(x, y, z);
122     }
123     dfs(1);
124     for (lg2[1] = 0, i = 2; i <= cnt_seq; ++i) lg2[i] = lg2[i >> 1] + 1;
125     for (j = 1; j <= lg2[cnt_seq]; ++j)
126         for (i = 1; i + (1 << j) - 1 <= cnt_seq; ++i)
127             st[i][j] = min(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
128     for (i = 1; i <= m; ++i) {
129         x = read();
130         if (tr[x].now) tr[x].now = 0, erase(tr[x].w);
131         else tr[x].now = 1, insert(tr[x].w);
132         printf("%lld\n", ans - LCA() << 1);
133     }
134     return 0;
135 }
136  
137 inline int read() {
138     static int x, sgn;
139     static char ch;
140     x = 0, sgn = 1, ch = getchar();
141     while (ch < '0' || '9' < ch) {
142         if (ch == '-') sgn = -1;
143         ch = getchar();
144     }
145     while ('0' <= ch && ch <= '9') {
146         x = x * 10 + ch - '0';
147         ch = getchar();
148     }
149     return sgn * x;
150 }
View Code

 

posted on 2015-04-23 21:42  Xs酱~  阅读(1222)  评论(0编辑  收藏  举报