zoukankan      html  css  js  c++  java
  • HDU 3726 Graph and Queries(平衡二叉树)(2010 Asia Tianjin Regional Contest)

    Description

    You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operations and you need to process them as requested. Here's a list of the possible operations that you might encounter:
    1)  Deletes an edge from the graph.
    The format is [D X], where X is an integer from 1 to M, indicating the ID of the edge that you should delete. It is guaranteed that no edge will be deleted more than once.
    2)  Queries the weight of the vertex with K-th maximum value among all vertexes currently connected with vertex X (including X itself).
    The format is [Q X K], where X is an integer from 1 to N, indicating the id of the vertex, and you may assume that K will always fit into a 32-bit signed integer. In case K is illegal, the value for that query will be considered as undefined, and you should return 0 as the answer to that query.
    3)  Changes the weight of a vertex.
    The format is [C X V], where X is an integer from 1 to N, and V is an integer within the range [-106, 106].

    The operations end with one single character, E, which indicates that the current case has ended.
    For simplicity, you only need to output one real number - the average answer of all queries.

    Input

    There are multiple test cases in the input file. Each case starts with two integers N and M (1 <= N <= 2 * 104, 0 <= M <= 6 * 104), the number of vertexes in the graph. The next N lines describes the initial weight of each vertex (-106 <= weight[i] <= 106). The next part of each test case describes the edges in the graph at the beginning. Vertexes are numbered from 1 to N. The last part of each test case describes the operations to be performed on the graph. It is guaranteed that the number of query operations [Q X K] in each case will be in the range [1, 2 * 105], and there will be no more than 2 * 105 operations that change the values of the vertexes [C X V].

    There will be a blank line between two successive cases. A case with N = 0, M = 0 indicates the end of the input file and this case should not be processed by your program.

    Output

    For each test case, output one real number � the average answer of all queries, in the format as indicated in the sample output. Please note that the result is rounded to six decimal places.
     
    题目大意:给一个n个点m条边的无向图,有三种询问,分别为删边、询问某子集内第k大权、修改某点权值,问数次询问后,第二种询问的值的平均数
    思路:用treap树维护一个强联通分量。离线处理所有询问,先删掉图中将会被删掉的边,从后往前询问,修改权值的询问也要稍作处理。
    PS:因为打错一个字母RE了半天……
     
      1 #include <cstdlib>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int MAXC = 500010;
      8 const int MAXN = 20010;
      9 const int MAXM = 60010;
     10 
     11 int key[MAXN], weight[MAXN], child[MAXN][2], size[MAXN];
     12 int stk[MAXN], top, poi_cnt;//not use point
     13 
     14 inline int newNode(int k) {
     15     int x = (top ? stk[top--] : ++poi_cnt);
     16     key[x] = k;
     17     size[x] = 1;
     18     weight[x] = rand();
     19     child[x][0] = child[x][1] = 0;
     20     return x;
     21 }
     22 
     23 inline void update(int &x) {
     24     size[x] = size[child[x][0]] + size[child[x][1]] + 1;//size[0]=0
     25 }
     26 
     27 inline void rotate(int &x, int t) {
     28     int y = child[x][t];
     29     child[x][t] = child[y][t ^ 1];
     30     child[y][t ^ 1] = x;
     31     update(x); update(y);
     32     x = y;
     33 }
     34 
     35 void insert(int &x, int k) {
     36     if (x == 0) x = newNode(k);
     37     else {
     38         int t = (key[x] < k);
     39         insert(child[x][t], k);
     40         if (weight[child[x][t]] < weight[x]) rotate(x, t);
     41     }
     42     update(x);
     43 }
     44 
     45 void remove(int &x, int k) {
     46     if(key[x] == k) {
     47         if(child[x][0] && child[x][1]) {
     48             int t = weight[child[x][0]] < weight[child[x][1]];
     49             rotate(x, t); remove(child[x][t ^ 1], k);
     50         }
     51         else {
     52             stk[++top] = x;
     53             x = child[x][0] + child[x][1];
     54         }
     55     }
     56     else remove(child[x][key[x] < k], k);
     57     if(x > 0) update(x);
     58 }
     59 
     60 struct Command {
     61     char type;
     62     int x, p;
     63 } commands[MAXC];
     64 
     65 int n, m, value[MAXN], from[MAXM], to[MAXM], removed[MAXM];
     66 
     67 int fa[MAXN];
     68 int getfather(int x) {
     69     if(fa[x] == x) return x;
     70     else return fa[x] = getfather(fa[x]);
     71 }
     72 
     73 int root[MAXN];
     74 
     75 void mergeto(int &x, int &y) {
     76     if(child[x][0]) mergeto(child[x][0], y);
     77     if(child[x][1]) mergeto(child[x][1], y);
     78     insert(y, key[x]);
     79     stk[++top] = x;
     80 }
     81 
     82 inline void addEdge(int x) {
     83     int u = getfather(from[x]), v = getfather(to[x]);
     84     if(u != v) {
     85         if(size[root[u]] > size[root[v]]) swap(u, v);
     86         fa[u] = v; mergeto(root[u], root[v]);
     87     }
     88 }
     89 
     90 int kth(int &x, int k) {
     91     if(x == 0 || k <= 0 || k > size[x]) return 0;
     92     int s = 0;
     93     if(child[x][1]) s = size[child[x][1]];
     94     if(k == s + 1) return key[x];
     95     if(k <= s) return kth(child[x][1], k);
     96     return kth(child[x][0], k - s - 1);
     97 }
     98 
     99 int query_cnt;
    100 long long query_tot;
    101 
    102 void query(int x, int k) {
    103     ++query_cnt;
    104     query_tot += kth(root[getfather(x)], k);
    105 }
    106 
    107 inline void change_value(int x, int v) {
    108     int u = getfather(x);
    109     remove(root[u], value[x]);
    110     insert(root[u], value[x] = v);
    111 }
    112 
    113 int main() {
    114     int kase = 0;
    115     size[0] = 0;
    116     while(scanf("%d%d", &n, &m) != EOF && n) {
    117         for(int i = 1; i <= n; ++i) scanf("%d", &value[i]);
    118         for(int i = 1; i <= m; ++i) scanf("%d%d", &from[i], &to[i]);
    119         memset(removed, 0, sizeof(removed));
    120 
    121         int c = 0;
    122         while(true) {
    123             char type;
    124             int x, p = 0, v = 0;
    125             scanf(" %c", &type);
    126             if(type == 'E') break;
    127             scanf("%d", &x);
    128             if(type == 'D') removed[x] = 1;
    129             if(type == 'Q') scanf("%d", &p);
    130             if(type == 'C') {
    131                 scanf("%d", &v);
    132                 p = value[x];
    133                 value[x] = v;
    134             }
    135             commands[c++] = (Command) {type, x, p};
    136         }
    137 
    138         top = poi_cnt = 0;
    139         for(int i = 1; i <= n; ++i) {
    140             fa[i] = i;
    141             root[i] = newNode(value[i]);
    142         }
    143         for(int i = 1; i <= m; ++i) if(!removed[i]) addEdge(i);
    144 
    145         query_tot = query_cnt = 0;
    146         for(int i = c - 1; i >= 0; --i) {
    147             if(commands[i].type == 'D') addEdge(commands[i].x);
    148             if(commands[i].type == 'Q') query(commands[i].x, commands[i].p);
    149             if(commands[i].type == 'C') change_value(commands[i].x, commands[i].p);
    150         }
    151         printf("Case %d: %.6f
    ", ++kase, query_tot/(double)query_cnt);
    152     }
    153     return 0;
    154 }
    View Code
  • 相关阅读:
    Rabbitmq 性能测试
    B+树图文详解
    图的概念和存储(邻接矩阵,邻接表)
    WebApi系列文章
    Asp.Net MVC项目集成Swagger
    正则表达式匹配两个特殊字符中间的内容
    数学常数e的含义
    十大排序算法总结
    C#集合类型大揭秘
    深入System.Web.Caching命名空间 教你Hold住缓存管理(三)
  • 原文地址:https://www.cnblogs.com/oyking/p/3218767.html
Copyright © 2011-2022 走看看