• 【HDU】3726 Graph and Queries


      1 #include<cstdio>
      2 #include<iostream>
      3 #define MAXN 400010
      4 #define PushUp(x) num[x] = num[next[x][0]] + num[next[x][1]] + 1;
      5 using namespace std;
      6 pair<int, int> edge[MAXN];
      7 int first[MAXN], next[MAXN], cost[MAXN], e;
      8 int father[MAXN];
      9 bool del[MAXN];
     10 struct ASK {
     11     char cmd;
     12     int x, k;
     13 } a[MAXN];
     14 struct SplayTree {
     15     int root;
     16     int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN];
     17     void Init() {
     18         root = next[0][0] = next[0][1] = pre[0] = num[0] = key[0] = 0;
     19     }
     20     inline void NewNode(int &x, int loc, int father, int val) {
     21         x = loc;
     22         next[x][0] = next[x][1] = 0;
     23         pre[x] = father;
     24         key[x] = val;
     25         num[x] = 1;
     26     }
     27     inline void Rotate(int x, int kind) {
     28         int y, z;
     29         y = pre[x];
     30         z = pre[y];
     31         next[y][!kind] = next[x][kind];
     32         pre[next[x][kind]] = y;
     33         next[z][next[z][1] == y] = x;
     34         pre[x] = z;
     35         next[x][kind] = y;
     36         pre[y] = x;
     37         PushUp(y);
     38     }
     39     void Splay(int x, int goal) {
     40         if (x != goal) {
     41             while (pre[x] != goal) {
     42                 if (next[pre[x]][0] == x)
     43                     Rotate(x, 1);
     44                 else
     45                     Rotate(x, 0);
     46             }
     47             PushUp(x);
     48             if (!goal)
     49                 root = x;
     50         }
     51     }
     52     int Select(int x, int k) {
     53         k = num[x] - k + 1;
     54         while (num[next[x][0]] + 1 != k) {
     55             if (num[next[x][0]] + 1 > k)
     56                 x = next[x][0];
     57             else {
     58                 k -= num[next[x][0]] + 1;
     59                 x = next[x][1];
     60             }
     61         }
     62         Splay(x, 0);
     63         return x;
     64     }
     65     void Insert(int x, int y, int val) {
     66         while (next[y][val > key[y]])
     67             y = next[y][val > key[y]];
     68         NewNode(next[y][val > key[y]], x, y, val);
     69     }
     70     void DFS(int x) {
     71         if (x) {
     72             DFS(next[x][0]);
     73             DFS(next[x][1]);
     74             Insert(x, root, key[x]);
     75             Splay(x, 0);
     76         }
     77     }
     78     void Join(int x, int y) {
     79         Splay(x, 0);
     80         Splay(y, 0);
     81         if (num[x] > num[y])
     82             swap(x, y);
     83         root = y;
     84         DFS(x);
     85     }
     86     int Query(int x, int k) {
     87         if (k < 1)
     88             return 0;
     89         Splay(x, 0);
     90         if (num[x] < k)
     91             return 0;
     92         return key[Select(x, k)];
     93     }
     94     void Change(int x, int val) {
     95         int a, b;
     96         Splay(x, 0);
     97         a = next[x][0];
     98         b = next[x][1];
     99         pre[a] = pre[b] = 0;
    100         if (a && b) {
    101             while (next[b][0])
    102                 b = next[b][0];
    103             next[b][0] = a;
    104             pre[a] = b;
    105             Splay(a, 0);
    106             Insert(x, a, val);
    107         } else if (a)
    108             Insert(x, a, val);
    109         else if (b)
    110             Insert(x, b, val);
    111         else
    112             key[x] = val;
    113         Splay(x, 0);
    114     }
    115 } spt;
    116 int INT() {
    117     bool neg;
    118     int res;
    119     char ch;
    120     while (ch = getchar(), !isdigit(ch) && ch != '-')
    121         ;
    122     if (ch == '-') {
    123         neg = true;
    124         res = 0;
    125     } else {
    126         neg = false;
    127         res = ch - '0';
    128     }
    129     for (; ch = getchar(), isdigit(ch);)
    130         res = res * 10 + ch - '0';
    131     return neg ? -res : res;
    132 }
    133 char CHAR() {
    134     char ch;
    135     while (ch = getchar(), !isalpha(ch))
    136         ;
    137     return ch;
    138 }
    139 int FindSet(int x) {
    140     if (x != father[x])
    141         father[x] = FindSet(father[x]);
    142     return father[x];
    143 }
    144 inline void AddEdge(int x, int val) {
    145     cost[e] = val;
    146     next[e] = first[x];
    147     first[x] = e++;
    148 }
    149 int main() {
    150     int ca = 1;
    151     double ans;
    152     int n, m, q, i, cnt;
    153     int x, y;
    154     while (true) {
    155         n = INT(), m = INT();
    156         if (!n && !m)
    157             break;
    158         spt.Init();
    159         for (e = 0, i = 1; i <= n; i++) {
    160             father[i] = i;
    161             first[i] = -1;
    162             AddEdge(i, INT());
    163         }
    164         for (i = 1; i <= m; i++) {
    165             edge[i] = make_pair(INT(), INT());
    166             del[i] = false;
    167         }
    168         for (q = 0;; q++) {
    169             a[q].cmd = CHAR();
    170             if (a[q].cmd == 'E')
    171                 break;
    172             a[q].x = INT();
    173             if (a[q].cmd == 'D')
    174                 del[a[q].x] = true;
    175             else {
    176                 a[q].k = INT();
    177                 if (a[q].cmd == 'C')
    178                     AddEdge(a[q].x, a[q].k);
    179             }
    180         }
    181         for (i = 1; i <= n; i++) {
    182             spt.NewNode(spt.root, i, 0, cost[first[i]]);
    183             first[i] = next[first[i]];
    184         }
    185         for (i = 1; i <= m; i++) {
    186             if (!del[i]) {
    187                 x = FindSet(edge[i].first);
    188                 y = FindSet(edge[i].second);
    189                 if (x != y) {
    190                     spt.Join(edge[i].first, edge[i].second);
    191                     father[x] = y;
    192                 }
    193             }
    194         }
    195         ans = cnt = 0;
    196         for (i = q - 1; i >= 0; i--) {
    197             if (a[i].cmd == 'Q') {
    198                 cnt++;
    199                 ans += spt.Query(a[i].x, a[i].k);
    200             } else if (a[i].cmd == 'D') {
    201                 x = FindSet(edge[a[i].x].first);
    202                 y = FindSet(edge[a[i].x].second);
    203                 if (x != y) {
    204                     spt.Join(edge[a[i].x].first, edge[a[i].x].second);
    205                     father[x] = y;
    206                 }
    207             } else {
    208                 spt.Change(a[i].x, cost[first[a[i].x]]);
    209                 first[a[i].x] = next[first[a[i].x]];
    210             }
    211         }
    212         printf("Case %d: %lf\n", ca++, ans / cnt);
    213     }
    214     return 0;
    215 }
  • 相关阅读:
    伺服电机常见故障分析汇总
    PLC常见四大故障及其处理方法
    Qt QString的arg()方法的使用
    Qt 线程池QThreadPool类、QRunnable类
    C++线程池的实现
    C++ List的用法
    C++语言堆栈的详细讲解
    QT中的QQueue类、C++中的queue类
    Qt platform plugin 'windows' 问题的解决方法
    电气接地的相关介绍
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2646503.html
Copyright © 2020-2023  润新知