# Solution

$pushup$中更新维护的 $mx$ 指向路径上权值最大的边的编号。

# Code

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

posted on 2018-09-24 07:19  cychester  阅读(191)  评论(0编辑  收藏  举报