UvaLive 5031 Graph and Queries(Treap+并查集)
来源:互联网 发布:java培训多少钱 编辑:程序博客网 时间:2024/05/22 14:14
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3032
思路:
1.三种操作:删除编号x的边;计算与结点x连通的点中,第k大权值;修改结点x的权值为c。
2.离线操作,按命令相反的顺序进行(先删除所有要删除的边,修改所有权值)。则操作变为加边和修改点的权值。
3.对于每个点建立一棵名次树。加边可通过并查集维护,对于边u-v,若点u与点v已连通则忽略,否则将点u与点v对应树合并:设u对应T1,点数为n1;v对应T2,点数为n2,若n1<n2,则将T1合并到T2,否则将T2合并到T1(即启发式合并,合并对应将一棵树所有点插入到另一棵树中)。查询操作对应名次树中求第k大值。修改时,记录每个点上一次修改时的值,则每次修改对应从树中删除当前值,然后插入该点的上一个值。
#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;struct Node{Node* ch[2];int r, v, s;Node(int v) :v(v) { ch[0] = ch[1] = NULL; r = rand(); s = 1; }bool operator < (const Node& rhs) const{return r < rhs.r;}int cmp(int x) const{if (x == v) return -1;return x < v ? 0 : 1;}void maintain(){s = 1;if (ch[0] != NULL) s += ch[0]->s;if (ch[1] != NULL) s += ch[1]->s;}};struct Treap{void rotate(Node* &o, int d){Node* k = o->ch[d ^ 1];o->ch[d ^ 1] = k->ch[d]; k->ch[d] = o;o->maintain(); k->maintain(); o = k;}void insert(Node* &o, int x){if (o == NULL){o = new Node(x);}else{int d = (x < o->v ? 0 : 1);insert(o->ch[d], x);if (o->ch[d] > 0) rotate(o, d ^ 1);}o->maintain();}void remove(Node* &o, int x){int d = o->cmp(x);if (d == -1){Node* u = o;if (o->ch[0] != NULL&&o->ch[1] != NULL){int d2 = (o->ch[0] > o->ch[1] ? 1 : 0);rotate(o, d2); remove(o->ch[d2], x);}else{if (o->ch[0] == NULL) o = o->ch[1];else o = o->ch[0];delete u;}}else{remove(o->ch[d], x);}if (o != NULL) o->maintain();}int kth(Node* o, int k){if (o == NULL || k <= 0 || k > o->s) return 0;int s = (o->ch[1] == NULL ? 0 : o->ch[1]->s);if (k == s + 1) return o->v;else if (k <= s) return kth(o->ch[1], k);else return kth(o->ch[0], k - s - 1);}void mergeto(Node* &src, Node* &dest){if (src->ch[0] != NULL) mergeto(src->ch[0], dest);if (src->ch[1] != NULL) mergeto(src->ch[1], dest);insert(dest, src->v);delete src;src = NULL;}void removetree(Node* &x){if (x->ch[0] != NULL) removetree(x->ch[0]);if (x->ch[1] != NULL) removetree(x->ch[1]);delete x;x = NULL;}};const int maxn = 20000 + 50;const int maxm = 60000 + 50;struct Que{int a, b, id;Que(){}Que(int a,int b,int c):a(a),b(b),id(c){}};int n, m;Treap tree;int fa[maxn];Node* root[maxn];Que q[maxn * 30];pair<int, int> e[maxm];int w[maxn], flag[maxm];void init(){memset(w, 0, sizeof(w));memset(flag, 0, sizeof(flag));for (int i = 1; i <= n; i++) fa[i] = i;}int Find(int x){return fa[x] == x ? x : fa[x] = Find(fa[x]);}void addEdge(int x, int y){int u = Find(x),v = Find(y);if (u == v) return;if (root[u]->s < root[v]->s){tree.mergeto(root[u], root[v]);fa[u] = v;}else{tree.mergeto(root[v], root[u]);fa[v] = u;}}int main(){#ifdef debufreopen("in.txt", "r", stdin);#endif // debugint cas = 0;srand((int)time(NULL));while (scanf("%d%d", &n, &m) != EOF && (n + m)){init();for (int i = 1; i <= n; i++){scanf("%d", &w[i]);}for (int i = 1; i <= m; i++) scanf("%d%d", &e[i].first, &e[i].second);char ch;int cnt = 0;while (scanf("%c", &ch)){if (ch == 'E') break;if (ch == 'Q'){int u, k;scanf("%d%d", &u, &k);q[++cnt] = Que(u, k, 2);}else if (ch == 'C'){int u, c;scanf("%d%d", &u, &c);int tmp = w[u];w[u] = c;q[++cnt] = Que(u, tmp, 0);}else if (ch == 'D'){int e;scanf("%d", &e);flag[e] = 1;q[++cnt] = Que(e, 0, 1);}}for (int i = 1; i <= n; i++){if (root[i] != NULL) tree.removetree(root[i]);root[i] = new Node(w[i]);}for (int i = 1; i <= m; i++){if (!flag[i]){addEdge(e[i].first, e[i].second);}}int sum = 0;double ans = 0.0;for (int i = cnt; i >=1; i--){if (q[i].id == 2){ans += tree.kth(root[Find(q[i].a)], q[i].b);sum++;}else if (q[i].id == 1){addEdge(e[q[i].a].first, e[q[i].a].second);}else if (q[i].id == 0){int rt = Find(q[i].a);tree.remove(root[rt], w[q[i].a]);tree.insert(root[rt], q[i].b);w[q[i].a] = q[i].b;}}printf("Case %d: %.6f\n", ++cas,ans/sum);}return 0;}
阅读全文
0 0
- UvaLive 5031 Graph and Queries(Treap+并查集)
- LA 5031 Graph and Queries (Treap + 并查集)
- uva live 5031 Graph and Queries(Treap x 并查集)
- LA 5031 Graph and Queries (【名次树(treap)】+【并查集】+【离线算法】)
- UVALive 5031 Graph and Queries(离线,treap)
- HDU 3276 Graph and Queries [离线+并查集+treap]
- hdu 3726 Graph and Queries , 天津 2010, LA 5031,并查集,Treap,离线处理
- 【UVALive】5031 Graph and Queries treap实现名次树
- Uva 5031 Graph and Queries(Treap)
- UVA 1479 Graph and Queries(Treap:名次树+并查集)
- HDU 3726 Graph and Queries 离线处理 treap + 并查集
- UVALive 5031 Graph and Queries
- LA - 5031 - Graph and Queries(平衡树Treap)
- LA 5031 Graph and Queries Treap
- LA 5031 Graph and Queries(Treap)
- UVALive 5031 Graph and Queries(名次树 rank tree)
- [Treap] LA5031 Graph and Queries
- hdu3726:Graph and Queries(treap+启发式合并+离线)
- 正式使用第一天
- Qt学习17——初识数据库SQLite(上)
- JDK7之Try-with-resources
- java中抽象类和接口的区别
- torch-luarocks在服务器安装软件
- UvaLive 5031 Graph and Queries(Treap+并查集)
- Android事件拦截机制分析
- JavaScript内存(相关)
- Android的ListView常用优化技巧
- Swoole-WebSocket-Chat 聊天室前后端demo
- HOOK钩子机制
- Android Scroll 滑动分析
- Modelsim打开、生成VCD文件
- 对泛型的认知