一起来学习一个treap【POJ 3458】&【LA 5031】
2017-02-11 21:06
441 查看
这是我的treap代码储存。
welcome!
welcome!
POJ 3458
链接:
题目来源代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; struct node{ node* ch[2]; int r,s,v,ans; node(int x,int y){ch[0] = ch[1] = NULL;r = rand();s = 1;v = x;ans = y;} int cmp(int x) { 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; } }; 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,int y) { if(o == NULL) o = new node(x,y); else { int d = (x < o->v ? 0 : 1); insert(o->ch[d],x,y); 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(); } int kth(node* &o,int k) { if(o == NULL || k <= 0 || k > o->s) return 0; int s = (o->ch[0] == NULL ? 0 : o->ch[0]->s); if(k == s+1) { printf("%d\n",o->ans); return o->v; } else if(k <= s) return kth(o->ch[0],k); else return kth(o->ch[1],k-s-1); } node * root; int main() { int len = 0,p,x,y; while(scanf("%d",&p) && p) { if(p == 1) { scanf("%d%d",&x,&y); insert(root,y,x); len++; } else { if(len == 0){printf("0\n");continue;} if(p == 2) x = kth(root,len); if(p == 3) x = kth(root,1); remove(root,x); len--; } } return 0; }
LA 5031
链接:
题目来源代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; struct node{ node *ch[2]; int r,v,s; node(int x){ch[0] = ch[1] = NULL; r = rand(); s = 1; v = x;} bool operator < (const node& rhs) const{return r < rhs.r;} int cmp(int x) { if(x == v) return -1; else return x < v ? 0 : 1; } void maintain() { s = 1; if(ch[1] != NULL) s += ch[1]->s; if(ch[0] != NULL) s += ch[0]->s; } }; 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 4000 (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 = 0; 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 = 500010; struct command{ char type; int x,p; }commands[maxc]; const int maxn = 20010; const int maxm = 60010; int n,m,weight[maxn],from[maxm],to[maxm],removed[maxm]; int pa[maxn]; int find(int x){return pa[x] != x ? pa[x] = find(pa[x]) : x;} node* root[maxn];//treap 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; } void add_edge(int x) { int u = find(from[x]),v = find(to[x]); if(u != v) { if(root[u]->s < root[v]->s){pa[u] = v;mergeto(root[u],root[v]);} else {pa[v] = u;mergeto(root[v],root[u]);} } } int query_cnt; long long query_tot; void query(int x,int k) { query_cnt++; query_tot += kth(root[find(x)],k); } void change_weight(int x,int v) { int u = find(x); remove(root[u],weight[x]); insert(root[u],v); weight[x] = v; } int main() { int kase = 0; while(scanf("%d%d",&n,&m) == 2 && n) { for(int i = 1;i <= n;i++) scanf("%d",&weight[i]); for(int i = 1;i <= m;i++) scanf("%d%d",&from[i],&to[i]); memset(removed,0,sizeof(removed)); int c = 0; for(;;) { char type; int x,p = 0, v = 0; scanf(" %c",&type); if(type == 'E')break; scanf("%d",&x); if(type == 'D') removed[x] = 1; if(type == 'Q') scanf("%d",&p); if(type == 'C') { scanf("%d",&v); p = weight[x]; weight[x] = v; } commands[c++] = (command){type,x,p}; } for(int i = 1;i <= n;i++) { pa[i] = i; if(root[i] != NULL) removetree(root[i]); root[i] = new node(weight[i]); } for(int i = 1;i <= m;i++) if(!removed[i]) add_edge(i); query_tot = query_cnt = 0; for(int i = c-1;i >= 0;i--) { if(commands[i].type == 'D') add_edge(commands[i].x); if(commands[i].type == 'Q') query(commands[i].x,commands[i].p); if(commands[i].type == 'C') change_weight(commands[i].x,commands[i].p); } printf("Case %d: %.6lf\n",++kase,query_tot/(double)query_cnt); } return 0; }
相关文章推荐
- 【treap tree】 HDOJ 3726 && LA 5031 && UVA 1479 Graph and Queries
- Jsp&Servelet 学习笔记-创建一个部署描述文件
- Jsp&Servelet 学习笔记- 映射一个Servlet实名到web.xml中
- 【学习点滴-数据结构-栈&队列】 用两个栈模拟一个队列
- 《Orange'S:一个操作系统的实现》学习笔记(三)--bochs
- 《Orange'S:一个操作系统的实现》学习笔记(二)
- Jsp&Servelet 学习笔记-写出一个 servelet 程序
- poj 3134 && LA 3621 Power Calculus (迭代加深深度优先搜索)
- 【学习点滴-数据结构-栈&队列】 颠倒一个栈。
- 【学习点滴-数据结构-栈&队列】设计一个min函数的栈
- Trie树学习小记 Poj 3630 & Hdu1671 Phone List
- Jsp&Servelet 学习笔记-对一个Servlet创建多个Mapping
- Jsp&Servelet 学习笔记-对一个Servlet创建多个Mapping
- 学习YUI.Ext第七日-View&JSONView Part Two-一个画室网站的案例
- 【学习点滴-数据结构-栈&队列】 用两个队列模拟一个栈
- Jsp&Servelet 学习笔记- 在tomcat上部署一个单独的servlet的程序(Ant)
- 引用的一个"英语学习网址"
- SharePoint【学习笔记】-- 【Upgrading&Version版本升级】:Content Type Feature(一.创建和部署一个基本的Content Type Feature)
- poj 2743 && LA 3403 Mobile Computing (mid-easy Search)