Treap LA5031
来源:互联网 发布:金融类的工作知乎 编辑:程序博客网 时间:2024/05/16 12:19
动态二插排序树的一种常用实现算法:Treap。
从树根向下递归时当然都是一般的BST方式,左小又大,一步步向下;而向上回溯时却是采用维护最大堆的方式,同时为了维护二叉排序树的基本特性,每次不是直接交换节点,而是旋转;
从基本的Treap中为了解题,衍生出了名次树,每个节点用一个数据记录该子树所有节点数,可以完成查询第K大数(第K小数),找任给的x在当前树中的名次;
注意maintain的实现方式和位置,位置很重要,基本原则就是每次更新了节点(添加,删除,旋转),最后都要维护一下;
本题其实还要复杂的多,用到了启发式合并(大概就是从后往前,逆序的意思?),然后同时维护多个Treap树,除了基本的insert,remove,还要完成合并两个树mergoto的操作,自然要用到基本的并查集,哎,白书上说让大家独立手拍;
这题综合性相当强,时间复杂度是n*logn*logn。
#include <cstdlib>struct node { node *ch[2]; int r; int v; int 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; }};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] > o) 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();}#include <cstdio>#include <cstring>#include <vector>//#include <fstream>using namespace std;const int maxc= 500000+10;struct Commond { char type; int x, p;}commonds[maxc];const int maxn=20000+10;const int maxm=60000+10;int n, m, weight[maxn], from[maxm], to[maxm], removed[maxm];int pa[maxn];int findset(int x) { return pa[x]!=x ? pa[x]=findset(pa[x]) : x;}node* root[maxn];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=findset(from[x]), v=findset(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[findset(x)],k);}void change_weight(int x,int v) { int u=findset(x); remove(root[u],weight[x]); insert(root[u],v); weight[x]=v;}int main(){// freopen("1.in","r",stdin); 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; } commonds[c++]= (Commond) {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 (commonds[i].type=='D') add_edge(commonds[i].x); if (commonds[i].type=='Q') query(commonds[i].x,commonds[i].p); if (commonds[i].type=='C') change_weight(commonds[i].x,commonds[i].p); } printf("Case %d: %.6lf\n",++kase,query_tot/(double)query_cnt); } return 0;}
- Treap LA5031
- [Treap] LA5031 Graph and Queries
- LA5031 Graph and Queries (Treap模版)
- Treap
- Treap
- Treap
- Treap
- Treap
- Treap
- treap
- Treap
- treap
- Treap
- treap
- Treap
- Treap
- treap
- Treap
- C/C++常见的编程题
- http请求开源框架: AsyncHttpClient
- 权限管理
- 10月15日面试之某视科技
- 基极分压射击偏置的共射放大电路
- Treap LA5031
- C、C++编程入口,常见的编程题
- android下多线程断点续传下载
- 图的有条件的寻路 BFS_search
- java实现登录验证码
- SQL-oracle
- 动物类
- 多线程断点下载:afinal-master
- 2.6 CMMI2级——供应商协议管理(Supplier Agreement Management)