zoukankan      html  css  js  c++  java
  • BZOJ 2594 水管局长

    Solution

    由于链信息不好直接维护, 所以新建一个节点存储边的权值, 并把这个节点连向 它所连的节点 $u$, $v$

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

    由于这题是只有删边, 没有添边, 所以可以离线倒序, 把删边变成添边。

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define rd read()
      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 
     19 int read() {
     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) {
    174             link(x, i + n);
    175             link(y, i + n);
    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) {
    189                 link(y, q[i].id + n);
    190                 link(x, q[i].id + n);
    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);
    197                 link(q[i].id + n, x);
    198                 link(q[i].id + n, y);
    199             }
    200         }
    201     }
    202     for (int i = 1; i <= Q; ++i)
    203         if (q[i].typ == 1)
    204             printf("%d
    ", ans[i]);
    205 }
    View Code
  • 相关阅读:
    02-vue过滤器和键盘修饰符
    01-vue指令
    webpack
    笔记:随机生成数、字符串
    笔记:long、longlong、int、float、NSString相互转换
    关于NSStringFromClass的一点见解
    iOS中UITextField常用设置和方法
    iOS 倒计时的一种实现
    iOS UITextField的代理<UITextFieldDelegate>的几点笔记
    iOS 单例模式简单实例
  • 原文地址:https://www.cnblogs.com/cychester/p/9694655.html
Copyright © 2011-2022 走看看