zoukankan      html  css  js  c++  java
  • CF487E Tourists

    Solution

    先Tarjan求出点双联通分量 并缩点。 用$multiset$维护 点双内的最小点权。

    容易发现, 点双内的最小点权必须包括与它相连的割边的点权。 所以我们必须想办法来维护。

    所以考虑用割点的点权更新它的父节点, 这样查询 点双 内的最小点权只需要查询本身的 $multiset$ 和 它的父亲节点就可以了。

    最后加个树剖就能过啦!

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<set>
      5 #include<vector>
      6 #define rd read()
      7 using namespace std;
      8 
      9 const int N = 2e5 + 5;
     10 const int inf = ~0U >> 2;
     11 
     12 int Head[N << 1], Tot;
     13 int head[N], tot;
     14 int low[N], dfn[N], cnt, col, c[N], nd_num, cut[N];
     15 int st[N], tp;
     16 int n, m, Q, a[N];
     17 int f[N << 1], top[N << 1], sz[N << 1], son[N << 1], mk, id[N << 1], dep[N << 1];
     18 
     19 vector<int> q[N];
     20 multiset<int> S[N << 2];
     21 
     22 struct edge {
     23     int nxt, to;
     24 }e[N << 2], E[N << 2];
     25 
     26 int read() {
     27     int X = 0, p = 1; char c = getchar();
     28     for (; c > '9' || c < '0'; c = getchar()) 
     29         if (c == '-') p = -1;
     30     for (; c >= '0' && c <= '9'; c = getchar())
     31         X = X * 10 + c - '0';
     32     return X * p;
     33 }
     34 
     35 void add(int u, int v) {
     36     e[++tot].to = v;
     37     e[tot].nxt = head[u];
     38     head[u] = tot;
     39 }
     40 
     41 void Add(int u, int v) {
     42     E[++Tot].to = v;
     43     E[Tot].nxt = Head[u];
     44     Head[u] = Tot;
     45 }
     46 
     47 void tarjan(int u) {
     48     low[u] = dfn[u] = ++cnt;
     49     st[++tp] = u;
     50     int flag = 0;
     51     for (int i = head[u]; i; i = e[i].nxt) {
     52         int nt = e[i].to;
     53         if (!dfn[nt]) {
     54             tarjan(nt);
     55             low[u] = min(low[u], low[nt]);
     56             if (low[nt] < dfn[u]) 
     57                 continue;
     58             col++; flag++;
     59             cut[u] = 1;
     60             for (; tp;) {
     61                 int z = st[tp--];
     62                 q[col].push_back(z);
     63                 if (z == nt)
     64                     break;
     65             }
     66             q[col].push_back(u);
     67         }
     68         else low[u] = min(low[u], dfn[nt]);
     69     }
     70     if (flag < 2 && u == 1)
     71         cut[u] = 0;
     72 }
     73 
     74 namespace SegT {
     75 
     76     int MIN[N << 3];
     77 
     78 #define mid ((l + r) >> 1)
     79 #define lson nd << 1
     80 #define rson nd << 1 | 1
     81     
     82     void up(int nd) {
     83         MIN[nd] = min(MIN[lson], MIN[rson]);
     84     }
     85 
     86     void modify(int pos, int d, int l, int r, int nd) {
     87         if (l == r) {
     88             MIN[nd] = d;
     89             return;
     90         }
     91         if (pos <= mid)
     92             SegT::modify(pos, d, l, mid, lson);
     93         else
     94             SegT::modify(pos, d, mid + 1, r, rson);
     95         SegT::up(nd);
     96     }
     97     int query(int L, int R, int l, int r, int nd) {
     98         if (L <= l && r <= R)
     99             return MIN[nd];
    100         int tmp = inf;
    101         if(L <= mid)
    102             tmp = min(tmp, SegT::query(L, R, l, mid, lson));
    103         if(mid < R)
    104             tmp = min(tmp, SegT::query(L, R, mid + 1, r, rson));
    105         return tmp;
    106     }
    107 
    108 #undef mid
    109 #undef lson
    110 #undef rson
    111 }
    112 
    113 namespace SP {
    114 
    115     void dfs1(int u) {
    116         sz[u] = 1;
    117         for (int i = Head[u]; i; i = E[i].nxt) {
    118             int nt = E[i].to;
    119             if (nt == f[u])
    120                 continue;
    121             f[nt] = u;
    122             dep[nt] = dep[u] + 1;
    123             SP::dfs1(nt);
    124             sz[u] += sz[nt];
    125             if(sz[nt] >= sz[son[u]])
    126                 son[u] = nt;
    127         }
    128     }
    129 
    130     void dfs2(int u) {
    131         id[u] = ++mk;
    132         if (!son[u])
    133             return;
    134         top[son[u]] = top[u];
    135         SP::dfs2(son[u]);
    136         for (int i = Head[u]; i; i = E[i].nxt) {
    137             int nt = E[i].to;
    138             if (nt == f[u] || nt == son[u])
    139                 continue;
    140             top[nt] = nt;
    141             SP::dfs2(nt);
    142         }
    143     }
    144 
    145     int query(int x, int y) {
    146         int re = inf, tmp;
    147         for (; top[x] != top[y];) {
    148             if (dep[top[x]] < dep[top[y]])
    149                 swap(x, y);
    150             tmp = SegT::query(id[top[x]], id[x], 1, mk, 1);
    151             re = min(tmp, re);
    152             x = f[top[x]];
    153         }
    154         if (dep[x] < dep[y])
    155             swap(x, y);
    156         tmp = SegT::query(id[y], id[x], 1, mk, 1);
    157         re = min(tmp, re);
    158         if (f[y] && y <= col)
    159             tmp = SegT::query(id[f[y]], id[f[y]], 1, mk, 1);
    160         re = min(tmp, re);
    161         return re;
    162     }
    163 }
    164 
    165 int main()
    166 {
    167     n = rd; m = rd; Q = rd;
    168     for (int i = 1; i <= n; ++i)
    169         a[i] = rd;
    170     for (int i = 1; i <= m; ++i) {
    171         int u = rd, v = rd;
    172         add(u, v); add(v, u);
    173     }
    174     tarjan(1);
    175     nd_num = col;
    176     for (int i = 1; i <= n; ++i)
    177         if (cut[i]) c[i] = ++nd_num;
    178     for (int i = 1; i <= col; ++i)
    179         for (int j = 0, len = q[i].size(); j < len; ++j) {
    180             int x = q[i][j];
    181             if (cut[x])
    182                 Add(c[x], i), Add(i, c[x]);
    183             else c[x] = i;
    184         }
    185     dep[1] = 1;
    186     SP::dfs1(1);
    187     top[1] = 1;
    188     SP::dfs2(1);
    189     for (int i = 1; i <= n; ++i) {
    190         int x = c[i];
    191         S[x].insert(a[i]);
    192         if(x > col)
    193             S[f[x]].insert(a[i]);
    194     }
    195     for (int i = 1; i <= nd_num; ++i) {
    196         int x = *S[i].begin();
    197         SegT::modify(id[i], x, 1, mk, 1);
    198     }
    199     for (; Q; Q--) {
    200         char ch = getchar();
    201         while (ch != 'A' && ch != 'C')
    202             ch = getchar();
    203         int u = rd, v = rd;
    204         if (ch == 'C') {
    205             swap(v, a[u]);
    206             S[c[u]].erase(S[c[u]].find(v));
    207             S[c[u]].insert(a[u]);
    208             int x = *S[c[u]].begin();
    209             SegT::modify(id[c[u]], x, 1, mk, 1);
    210             if (c[u] <= col)
    211                 continue;
    212             S[f[c[u]]].erase(S[f[c[u]]].find(v));
    213             S[f[c[u]]].insert(a[u]);
    214             x = *S[f[c[u]]].begin();
    215             SegT::modify(id[f[c[u]]], x, 1, mk, 1);
    216         }
    217         else {
    218             if (u == v) printf("%d
    ", a[u]);
    219             else printf("%d
    ", SP::query(c[u], c[v]));
    220         }
    221     }
    222 }
    View Code
  • 相关阅读:
    TSQL 常用日期格式
    TSQL数据类型研究_tinyint
    设置数据库状态
    判断存储过程、触发器、视图是否存在并删除
    TSQL日期函数
    TSQL常用日期函数
    TSQL单双引号分隔符相关
    动态存储过程
    TSQL类型转换函数
    modelsim保存仿真结果,以及打开保存的仿真结果的波形wlf文件(经过实验,真实可用)
  • 原文地址:https://www.cnblogs.com/cychester/p/9677634.html
Copyright © 2011-2022 走看看