【HDOJ】3726 Graph and Queries
2015-10-20 11:27
399 查看
Treap的基础题目,Treap是个挺不错的数据结构。
/* */ #include <iostream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 typedef struct { char c; int x, y; } Cmd; typedef struct Node { Node* ch[2]; int r, v, s; Node() {} Node(int v_) { ch[0] = ch[1] = NULL; r = rand(); v = v_; s = 1; } friend bool operator<(const Node& a, const Node& b) { return a.r < b.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; } } Node; 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]->r > o->r) 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]->r > o->ch[1]->r ? 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(); } const int maxc = 5e5+5; const int maxn = 2e4+5; const int maxm = 6e4+5; Cmd cmd[maxc]; Node* rt[maxn]; int W[maxn], pre[maxn]; int U[maxm], V[maxm]; bool mark[maxm]; int find(int x) { if (x == pre[x]) return x; return pre[x] = find(pre[x]); } 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; } void mergeto(Node*& src, Node*& des) { if (src->ch[0] != NULL) mergeto(src->ch[0], des); if (src->ch[1] != NULL) mergeto(src->ch[1], des); insert(des, src->v); delete src; src = NULL; } void addEdge(int k) { int u = U[k], v = V[k]; int fu = find(u), fv = find(v); if (fu != fv) { if (rt[fu]->s < rt[fv]->s) { pre[fu] = fv; mergeto(rt[fu], rt[fv]); } else { pre[fv] = fu; mergeto(rt[fv], rt[fu]); } } } 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); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif int tt = 0; int n, m, nc; int x, y; char s[3]; __int64 tot, ans; while (scanf("%d %d",&n,&m)!=EOF && (n||m)) { rep(i, 1, n+1) scanf("%d", &W[i]); rep(i, 1, m+1) scanf("%d %d", &U[i], &V[i]); memset(mark, false, sizeof(mark)); nc = 0; while (scanf("%s", s)!=EOF && s[0]!='E') { cmd[nc].c = s[0]; if (s[0] == 'D') { scanf("%d", &x); cmd[nc].x = x; mark[x] = true; } else if (s[0] == 'Q') { scanf("%d %d", &x, &y); cmd[nc].x = x; cmd[nc].y = y; } else if (s[0] == 'C') { scanf("%d %d", &x, &y); cmd[nc].x = x; cmd[nc].y = W[x]; W[x] = y; } ++nc; } rep(i, 1, n+1) { pre[i] = i; if (rt[i] != NULL) removetree(rt[i]); rt[i] = new Node(W[i]); } rep(i, 1, m+1) { if (!mark[i]) addEdge(i); } ans = tot = 0; per(i, 0, nc) { if (cmd[i].c == 'D') { addEdge(cmd[i].x); } else if (cmd[i].c == 'Q') { int fx = find(cmd[i].x); ++tot; ans += kth(rt[fx], cmd[i].y); } else if (cmd[i].c == 'C') { int fx = find(cmd[i].x); remove(rt[fx], W[cmd[i].x]); insert(rt[fx], cmd[i].y); W[cmd[i].x] = cmd[i].y; } } printf("Case %d: %.06lf\n", ++tt, 1.0*ans/tot); } #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
相关文章推荐
- Field 'id' doesn't have a default value
- 通过NameValuePairsValueProvider对象来获取指定前缀的Key
- Java中的String类和StringBuilder类复习
- Easyui Form增加myLoad方法,使其支持二级数据对象,Fix版本
- Linguistic Data Consortium (LDC)
- druid连接池配置
- Leetcode108: Unique Binary Search Trees II
- Version和Build的区别
- NGUI坑之首行缩进
- AndroidUI-TxetView嵌套Html的使用
- UITabbar UINavigationBar
- 【最新API翻译】 Bluetooth--BluetoothAdapter API 翻译
- Qt使用教程之创建Qt Quick项目
- 「8-Queens Problem」皇后问题局部极值启发式搜索方法
- UINavigationItem UINavigationBar 关系分析
- STL学习笔记——序列式容器deque
- 浅谈UIScrollView
- VS2005编译问题LINK : E:/aaa/Debug/aaa.exe not found or not built by the last incremental link; performin
- 开速开发:UIView与XIB关联
- easyui 批量 移除行,