uva live 5031 Graph and Queries(Treap x 并查集)
2015-09-01 15:29
525 查看
题意:
。。。
同样收录在 HDU 3726,不过hdu貌似有时候 re 会报 wa,不方便调错。。
思路:
教科书题。。
用来练 Treap 模板很合适
尝试写了几发GC, 用stack来装指针。。发现效率都不是很高。。还很耗内存。。于是放弃了。。
。。。
同样收录在 HDU 3726,不过hdu貌似有时候 re 会报 wa,不方便调错。。
思路:
教科书题。。
用来练 Treap 模板很合适
尝试写了几发GC, 用stack来装指针。。发现效率都不是很高。。还很耗内存。。于是放弃了。。
// 纯动态 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <set> #include <queue> #include <map> #include <cmath> #include <cassert> #include <stack> #include <stdexcept> using namespace std; #define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i)) const int N = 20000 + 5; typedef long long LL; struct Node { Node* ch[2]; int fix, key, cnt, sz; inline void update() { sz = cnt + ch[0]->sz + ch[1]->sz; } inline bool lt(int other) const { return key < other; } } *nil; Node* allocate_node(int key) { Node* nd = new Node(); nd->ch[0] = nd->ch[1] = nil; nd->sz = nd->cnt = 1; nd->key = key; nd->fix = rand(); return nd; } void free_node(Node* rt) { if ( rt->ch[0] != nil ) free_node(rt->ch[0]); if ( rt->ch[1] != nil ) free_node(rt->ch[1]); delete rt; } // d: 0 - right rotate, 1 - left rotate void Rot(Node* &rt, int d) { Node *t = rt->ch[d]; rt->ch[d] = t->ch[1^d]; t->ch[1^d] = rt; rt->update(); t->update(); rt = t; } void Insert(Node* &rt, int key) { if ( rt != nil ) { if ( key == rt->key ) { ++ rt->cnt; } else { int d = rt->lt(key); // insert into ch[d] Insert(rt->ch[d], key); if ( rt->ch[d]->fix < rt->fix ) Rot(rt, d); } } else { rt = allocate_node(key); } rt->update(); } void Erase(Node* &rt, int key) { if ( rt != nil ) { if ( rt->key == key ) { if ( rt->cnt > 1 ) { -- rt->cnt; } else { if ( rt->ch[0] == nil && rt->ch[1] == nil ) { rt = nil; return; } else { int d = rt->ch[0]->fix > rt->ch[1]->fix; Rot(rt, d); Erase(rt->ch[1^d], key); } } } else { int d = rt->lt(key); Erase(rt->ch[d], key); } rt->update(); } else { //cout << "not found" << endl; } } int GetKth(const Node* rt, int k) { if ( k <= rt->ch[0]->sz ) return GetKth(rt->ch[0], k); k -= rt->ch[0]->sz + rt->cnt; if ( k <= 0 ) return rt->key; if ( k <= rt->ch[1]->sz ) return GetKth(rt->ch[1], k); else { //throw runtime_error("k is larger than size"); while (1); } } void MergeTo(Node* src, Node* &dst) { if ( src == nil ) return; queue<Node*> q; q.push(src); while ( !q.empty() ) { Node* u = q.front(); q.pop(); for(int i = 0; i < u->cnt; ++ i) Insert(dst, u->key); if ( u->ch[0] != nil ) q.push(u->ch[0]); if ( u->ch[1] != nil ) q.push(u->ch[1]); } free_node(src); } void treap_global_init() { nil = new Node(); memset(nil, 0, sizeof(Node)); nil->fix = INT_MAX; } const int MaxV = 2e4 + 5, MaxE = 6e4 + 5; struct Op { char type; int x, y; } ops[500005]; int weight[MaxV], can[MaxE], edges[MaxE][2]; Node *tr[MaxV]; namespace UF { int pa[MaxV]; void init(int n) { rep(i, 0, n-1) pa[i] = i; } int find(int x) { return x == pa[x] ? x : pa[x] = find(pa[x]); } void Union(int x, int y, int ctl = 0) { int px = find(x), py = find(y); if ( px != py ) { if ( tr[px]->sz > tr[py]->sz ) { if ( ctl ) { MergeTo(tr[py], tr[px]); } pa[py] = px; } else { if ( ctl ) { MergeTo(tr[px], tr[py]); } pa[px] = py; } } } }; int main() { #ifdef _LOCA_ENV_ freopen("input.in", "r", stdin); #endif // _LOCA_ENV /// treap init /// treap_global_init(); /// start here /// int n, m, cas = 0; while ( scanf("%d%d", &n, &m) != EOF && n ) { rep(i, 0, n-1) scanf("%d", weight + i); rep(i, 0, m-1) { can[i] = 1; scanf("%d%d", &edges[i][0], &edges[i][1]); -- edges[i][0], -- edges[i][1]; } int onm = 0; while ( 1 ) { char op; int x, y, z; for (op = getchar(); op == ' ' || op == '\n'; op = getchar()); ops[onm].type = op; if ( op == 'D' ) { scanf("%d", &x); -- x; ops[onm].x = x; can[x] = 0; } else if ( op == 'Q' ) { scanf("%d%d", &x, &y); -- x; ops[onm].x = x; ops[onm].y = y; } else if ( op == 'C' ) { scanf("%d%d", &x, &y); -- x; ops[onm].x = x; ops[onm].y = weight[x]; weight[x] = y; } else break; ++ onm; } UF::init(n); rep(i, 0, n-1) { tr[i] = nil; Insert(tr[i], weight[i]); } rep(i, 0, m-1) if ( can[i] ) UF::Union(edges[i][0], edges[i][1], 1); double tot = 0, qnm = 0;; for (int o = onm - 1; o >= 0; -- o) { int tmp = -1; if ( ops[o].type == 'Q' ) { int x = UF::find(ops[o].x); //cout << " root " << x << " , "<< tr[x].size() << endl; if ( ops[o].y >= 1 && ops[o].y <= tr[x]->sz ) { tmp = GetKth(tr[x], tr[x]->sz + 1 - ops[o].y); tot += tmp; } qnm += 1; } else if ( ops[o].type == 'C' ) { int x = UF::find(ops[o].x); Erase(tr[x], weight[ops[o].x]); Insert(tr[x], ops[o].y); weight[ops[o].x] = ops[o].y; } else if ( ops[o].type == 'D' ) { int u = edges[ops[o].x][0], v = edges[ops[o].x][1]; UF::Union(u, v, 1); } } double ans = tot / qnm; printf("Case %d: %.6f\n", ++ cas, ans); rep(i, 0, n-1) { int x = UF::find(i); if ( tr[x] != nil ) { free_node(tr[x]); tr[x] = nil; } } } return 0; }
相关文章推荐
- Myslq 启动报错The server quit without updating PID file
- 【iOS知识学习】_iPhone学习多个UITextField 键盘弹起
- [Bluetooth API]使用Irprops库搜索蓝牙设备
- iOS开发 UIScrollView自带的缩放功能(简单的例子)
- div设置contentEditable="true"作为文本编辑器,定位光标解决办法
- UITouch
- Git+gerrit user guide
- [Bluetooth(SDK)]使用WinSock搜索蓝牙设备
- 【LeetCode】225. Implement Stack using Queues
- UIImageView响应点击事件
- 1099. Build A Binary Search Tree (30)
- Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'Info
- 【LeetCode】232. Implement Queue using Stacks
- phalcon query 如何找bug
- UIView的基本使用
- 跟随鼠标NGUI
- 十六进制的颜色值转成RGB UIColor
- 使用UIView的animation
- UINavigationController 弹出新的UIViewController时,setNavigationBarHidden失效的问题
- ios uitableview 去掉多余的空行