UOJ 274 温暖会指引我们前进 - LCT

Solution

更新掉路径上温暖度最小的边就可以了~

Code

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define ll long long
  5 #define rd read()
  6 using namespace std;
  7 
  8 const int N = 4e5 + 5;
  9 const int inf = ~0U >> 1;
 10 
 11 int n, m, fa[N];
 12 
 13 struct edge {
 14     int u, v, t, w;
 15 }e[N];
 16 
 17 int read() {
 18     int X = 0, p = 1; char c = getchar();
 19     for (; c > '9' || c < '0'; c = getchar())
 20         if (c == '-') p = -1;
 21     for (; c >= '0' && c <= '9'; c = getchar())
 22         X = X * 10 + c - '0';
 23     return X * p;
 24 }
 25 
 26 int anc(int x) {
 27     return fa[x] == x ? x : fa[x] = anc(fa[x]);
 28 }
 29 
 30 namespace LCT {
 31     int f[N], ch[N][2], val[N], mn[N], tun[N];
 32     ll sum[N];
 33 #define lc(x) ch[x][0]
 34 #define rc(x) ch[x][1]
 35 
 36     int isroot(int x) {
 37         return lc(f[x]) != x && rc(f[x]) != x;
 38     }
 39 
 40     int get(int x) {
 41         return rc(f[x]) == x;
 42     }
 43 
 44     void up(int x) {
 45         mn[x] = val[x];
 46         sum[x] = e[val[x]].t;
 47         if (e[mn[lc(x)]].w < e[mn[x]].w) mn[x] = mn[lc(x)];
 48         if (e[mn[rc(x)]].w < e[mn[x]].w) mn[x] = mn[rc(x)];
 49         if (lc(x)) sum[x] += sum[lc(x)];
 50         if (rc(x)) sum[x] += sum[rc(x)];
 51     }
 52 
 53     void rev(int x) {
 54         swap(lc(x), rc(x));
 55         tun[x] ^= 1;
 56     }
 57 
 58     void pushdown(int x) {
 59         if (tun[x]) {
 60             if (lc(x)) rev(lc(x));
 61             if (rc(x)) rev(rc(x));
 62             tun[x] = 0;
 63         }
 64     }
 65 
 66 int st[N], tp;
 67 
 68     void pd(int x) {
 69         while (!isroot(x)) {
 70             st[++tp] = x;
 71             x = f[x];
 72         }
 73         pushdown(x);
 74         while (tp) pushdown(st[tp--]);
 75     }
 76 
 77     void rotate(int x) {
 78         int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1];
 79         if (!isroot(old)) ch[oldf][get(old)] = x;
 80         ch[x][get(x) ^ 1] = old;
 81         ch[old][get(x)] = son;
 82         f[old] = x; f[x] = oldf; f[son] = old;
 83         up(old); up(x);
 84     }
 85 
 86     void splay(int x) {
 87         pd(x);
 88         for (; !isroot(x); rotate(x)) 
 89             if (!isroot(f[x]))
 90                 rotate(get(f[x]) == get(x) ? f[x] : x);
 91     }
 92 
 93     void access(int x) {
 94         for (int y = 0; x; y = x, x = f[x])
 95             splay(x), ch[x][1] = y, up(x);
 96     }
 97 
 98     int findr(int x) {
 99         access(x); splay(x);
100         while (lc(x)) pushdown(x), x = lc(x);
101         return x;
102     }
103 
104     void mroot(int x) {
105         access(x); splay(x); rev(x);
106     }
107 
108     void split(int x, int y) {
109         mroot(x); access(y); splay(y);
110     }
111 
112     void link(int x, int y) {
113         mroot(x);
114         f[x] = y;
115     }
116 
117     void cut(int x, int y) {
118         split(x, y);
119         f[x] = ch[y][0] = 0;
120     }
121 }
122 using namespace LCT;
123 
124 int main()
125 {
126     e[0].w = inf;
127     n = rd; m = rd;
128     for (int i = 1; i <= n; ++i)
129         fa[i] = i;
130     for (int i = 1; i <= m; ++i)
131         val[i + n] = i;
132     char op[10];
133     for (int i = 1; i <= m; ++i) {
134         scanf("%s", op);
135         if (op[0] == 'f') {
136             int id = rd + 1;
137             e[id].u = rd + 1;
138             e[id].v = rd + 1;
139             e[id].w = rd;
140             e[id].t = rd;
141             int x = e[id].u, y = e[id].v;
142             if (anc(x) != anc(y)) {
143                 link(id + n, x);
144                 link(id + n, y);
145                 x = anc(x); y = anc(y);
146                 fa[x] = y;
147             }
148             else {
149                 split(x, y);
150                 int t = mn[y];
151                 if (e[id].w < e[t].w) 
152                     continue;
153                 cut(t + n, e[t].u);
154                 cut(t + n, e[t].v);
155                 link(id + n, e[id].u);
156                 link(id + n, e[id].v);
157             }
158         }
159         else if(op[0] == 'm') {
160             int x = rd + 1, y = rd + 1;
161             if (anc(x) != anc(y)) {
162                 puts("-1"); continue;
163             }
164             if (x == y) {puts("0"); continue;}
165             split(x, y);
166             printf("%lld\n", sum[y]);
167         }
168         else {
169             int id = rd + 1;
170             e[id].t = rd;
171             mroot(id + n);
172         }
173     }
174 }
View Code

猜你喜欢

转载自www.cnblogs.com/cychester/p/9696750.html
LCT