• UOJ 274 温暖会指引我们前进


    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
    ", sum[y]);
    167         }
    168         else {
    169             int id = rd + 1;
    170             e[id].t = rd;
    171             mroot(id + n);
    172         }
    173     }
    174 }
    View Code
  • 相关阅读:
    python实现读取并显示图片的两种方法
    如何在jupyter中安装R
    FPGA设计千兆以太网MAC(3)——数据缓存及位宽转换模块设计与验证
    FPGA设计千兆以太网MAC(2)——以太网协议及设计规划
    FIFO深度计算
    【不定期更新】FPGA/IC岗位常见笔试面试题总结(基础知识)
    【原创】建立与保持时间裕量详细分析
    利用ZYNQ SOC快速打开算法验证通路(6)——利用AXI总线实时配置sysGen子系统
    【转载】泰勒展开式
    利用ZYNQ SOC快速打开算法验证通路(5)——system generator算法IP导入IP integrator
  • 原文地址:https://www.cnblogs.com/cychester/p/9696750.html
Copyright © 2020-2023  润新知