题目链接:https://vjudge.net/contest/159527#problem/A

题意:(求一个 图 中的连通分量中的 第 k 大)

一张图,n 个点,m 条边,

有一些操作:

删除 ID 为 x 的边,(从 1 到 m);

询问 x 所在的连通分量 里面第 k 大的权值;

把结点 X 的权值 改成 V;

求:

所有的询问后,计算平均值;

每个连通分量都是一颗Treap树,加边操作,就是树的合并;

刘汝佳采用的是离线算法,我还是第一次听说,但是还是可以按照题意直接模拟的(我猜,但是很麻烦);因为在Treap中删边不同于删点;

什么是离线算法呢?

把操作顺序反过来处理,执行完所有 删除边操作,然后建Treap,要是不在同一个连通分量里面(并查集判断),这就涉及到递归合并Treap树了,这里采用了启发式合并;

然后反向操作,遇到 D,就是加边(加边操作同上),

询问,就是在 X 所在连通分量里面,寻找第 k 大;

改权,就是删除这个点,然后从新加点;

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 struct Node
  6 {
  7     Node *ch[2];
  8     int r;  //优先级
  9     int v;  //值
 10     int s;  //结点总数
 11
 12     Node(int v):v(v)
 13     {
 14         ch[0] = ch[1] = NULL;
 15         r = rand();
 16         s = 1;
 17     }
 18
 19     bool operator < (const Node& rhs) const
 20     {
 21         return r < rhs.r;
 22     }
 23
 24     int cmp(int x) const
 25     {
 26         if(x==v) return -1;
 27         return x < v ? 0 : 1;
 28     }
 29
 30     void maintain()
 31     {
 32         s = 1;
 33         if(ch[0]!=NULL) s+=ch[0]->s;
 34         if(ch[1]!=NULL) s+=ch[1]->s;
 35     }
 36
 37
 38 };
 39
 40 void rotate(Node* &o,int d)
 41 {
 42     Node* k = o->ch[d^1];
 43     o->ch[d^1] = k ->ch[d];
 44     k->ch[d] = o;
 45     o->maintain();
 46     k->maintain();
 47     o = k;
 48 }
 49
 50 void insert(Node* &o,int x)
 51 {
 52     if(o==NULL) o = new Node(x);
 53     else
 54     {
 55         int d = (x < o->v? 0 : 1);
 56         insert(o->ch[d],x);
 57         if(o->ch[d]->r > o->r)
 58             rotate(o,d^1);
 59     }
 60     o->maintain();
 61 }
 62
 63 void remove(Node* &o,int x)
 64 {
 65     int d = o->cmp(x);
 66     if(d==-1)
 67     {
 68         Node* u = 0;
 69         if(o->ch[0]!=NULL&&o->ch[1]!=NULL)
 70         {
 71             int d2 = (o->ch[0]->r > o->ch[1]->r ? 1 : 0);
 72             rotate(o,d2);
 73             remove(o->ch[d2],x);
 74         }
 75         else
 76         {
 77             if(o->ch[0]==NULL)
 78                 o = o->ch[1];
 79             else o = o->ch[0];
 80         }
 81     }
 82     else
 83         remove(o->ch[d],x);
 84
 85     if(o!=NULL) o->maintain();
 86 }
 87
 88
 89 const int maxc = 500000 + 10;
 90 struct Command
 91 {
 92     char type;
 93     int x,p;
 94 } commands[maxc];
 95
 96 const int maxn = 20000 + 10;
 97 const int maxm = 60000 + 10;
 98 int n,m;
 99 int weight[maxn],from[maxm],to[maxm],removed[maxm];
100
101
102 int pa[maxn];
103 int findset(int x)
104 {
105     return pa[x]!=x ? pa[x] = findset(pa[x]):x;
106 }
107
108 Node* root[maxn];   //Treap
109
110 int kth(Node* o,int k)
111 {
112     if(o==NULL||k<=0||k> o->s) return 0;
113     int s = (o->ch[1]==NULL?0:o->ch[1]->s);
114     if(k==s+1) return o->v;
115     else if(k<=s) return kth(o->ch[1],k);
116     else return kth(o->ch[0],k-s-1);
117 }
118
119 void mergeto(Node* &src,Node* &dest)
120 {
121     if(src->ch[0]!=NULL) mergeto(src->ch[0],dest);
122     if(src->ch[1]!=NULL) mergeto(src->ch[1],dest);
123     insert(dest,src->v);
124     delete src;
125     src = NULL;
126 }
127
128 void removetree(Node* &x)
129 {
130     if(x->ch[0]!=NULL) removetree(x->ch[0]);
131     if(x->ch[1]!=NULL) removetree(x->ch[1]);
132     delete x;
133     x = NULL;
134 }
135
136 void add_edge(int x)
137 {
138     int u = findset(from[x]),v=findset(to[x]);
139     if(u!=v)
140     {
141         if(root[u]->s < root[v]->s)
142         {
143             pa[u] = v;
144             mergeto(root[u],root[v]);
145         }
146         else
147         {
148             pa[v] = u;
149             mergeto(root[v],root[u]);
150         }
151     }
152 }
153
154 int query_cnt;
155 long long query_tot;
156 void query(int x,int k)
157 {
158     query_cnt++;
159     query_tot +=kth(root[findset(x)],k);
160 }
161
162 void change_weight(int x,int v)
163 {
164     int u = findset(x);
165     remove(root[u],weight[x]);
166     insert(root[u],v);
167     weight[x] = v;
168 }
169
170
171 int main()
172 {
173     int kase = 0;
174     while(scanf("%d%d",&n,&m)==2&&n)
175     {
176         for(int i=1; i<=n; i++)
177             scanf("%d",&weight[i]);
178         for(int i=1; i<=m; i++)
179             scanf("%d%d",&from[i],&to[i]);
180         memset(removed,0,sizeof(removed));
181
182         int c = 0;
183         for(;;)
184         {
185             char type;
186             int x,p=0,v = 0;
187             scanf(" %c",&type);
188             if(type=='E') break;
189             scanf("%d",&x);
190             if(type=='D') removed[x]= 1;    //删掉的边
191             if(type=='Q') scanf("%d",&p);
192             if(type=='C')
193             {
194                 scanf("%d",&v);
195                 p = weight[x];
196                 weight[x] = v;
197             }
198             commands[c++] = (Command)
199             {
200                 type,x,p
201             };
202         }
203
204         //最终的图
205         for(int i=1; i<=n; i++)
206         {
207             pa[i] = i;
208             if(root[i]!=NULL) removetree(root[i]);
209             root[i] = new Node(weight[i]);
210         }
211         for(int i=1; i<=m; i++)
212         {
213             if(!removed[i]) //id为i这条边没有被删掉
214                 add_edge(i);
215         }
216
217         query_cnt = query_tot = 0;
218         for(int i=c-1; i>=0; i--)
219         {
220             if(commands[i].type=='D') add_edge(commands[i].x);  //加上边
221             if(commands[i].type=='Q') query(commands[i].x,commands[i].p);//第p大
222             if(commands[i].type=='C') change_weight(commands[i].x,commands[i].p);
223         }
224
225         printf("Case %d: %.6lf\n",++kase,query_tot/(double)query_cnt);
226
227     }
228
229
230
231     return 0;
232 }

View Code

转载于:https://www.cnblogs.com/TreeDream/p/6735840.html

LA 5031 图询问相关推荐

  1. 浅谈分布式系统一致性之3PC协议

    一.写在前面 分布式系统一致性专题本期该写 3PC 协议了,上周太忙没有时间更新,就拿了之前的旧文章做了一些调整重发了一下,还望各位读者海涵. 后面大约还有3期:Paxos 协议.Raft 协议等,先 ...

  2. MAX9814高性能麦克风

    卓大大您好,我想问一下.我这里红色圈住的部分功能是什么,我仿真的时候加入这部分,给我一种模电里滤波的感觉? ▲ CSDN中实验电路(带有错误)   你的感觉是对的.我又重新看了一下你发送过来的这张图, ...

  3. (转)使用vsphere client 克隆虚拟机

    使用vsphere client 克隆虚拟机 分类: linux2012-10-29 16:59 292人阅读 评论(0) 收藏 举报 免费的VMWare ESXi5.0非常强大,于是在vSphere ...

  4. 虚拟化之vmware-vsphere (web) client

    两种客户端 vsphere client 配置>软件>高级设置里的变量 uservars.supressshellwarning=1 vsphere web client 安装完vSphe ...

  5. android studio linux 字体,Android Studio代码字体模糊解决方法

    HDU3394:Railway 传送门 点双练习. 对于一张图,询问有多少条边不属于任意一个点双和多少条边至少属于两个点双. 显然,一张图里有多少个桥就是第一问的答案. 对于第二问,考虑对于一个点双, ...

  6. UIPower交互设计 - 《UI的革命》文字版

    演讲者:UIPower用户体验部部长 陆国新博士 <UI的革命>第二部:<交互设计>,共分五讲: 第一讲:<交互设计的成功要素>视频地址:http://www.tu ...

  7. 虚拟服务器的克隆,使用vsphere client 克隆虚拟机的具体操作步骤(图文教程)

    随着虚拟机的大量使用,用户在使用过程中也会遇到一些疑问和问题,正睿服务器作为Vmware的合作伙伴,今天就来与大家分享一下使用VSphere Client克隆虚拟机的知识. 用户疑问:采用 VMWar ...

  8. 【天池月饼活动】基于自然语言处理文本生成与轮询问答与依图生文与中秋月饼配图

    文章目录 活动要求 项目演示 自然语言处理文本生成之对联上下联对答: 自然语言处理文本生成之依图生文: 多级轮询月饼对话 自动生成月饼 代码讲解 自从我前天进入阿里天池实验室,我就被他吸粉了,嫖了他的 ...

  9. 【Linux编程】一、Linux常见指令和权限理解(思维导图总结)

    文章目录 Linux下基本指令 01.ls 指令 02.pwd 指令 03 cd 指令 04.mkdir 指令 05.rmdir 指令 06.rm 指令 07.tree 指令 08.cp 指令 09. ...

最新文章

  1. HAL Flat Display Driver Demystified
  2. Android O限制系统全屏进一步遏制手机勒索
  3. Kotlin 和Spring WebFlux
  4. sql 之as(Aliases)别名(mysql)
  5. 男科医生到底有多不正经… | 今日最佳
  6. laravel 导出插件
  7. 2.4 1死锁的概念(1)
  8. Pandas入门教程(一)
  9. python mpi4py 读取json_mpi4py 点到点通信总结
  10. [从零开始学习FPGA编程-27]:进阶篇 - 基本组合电路-数据比较器(Verilog语言)
  11. My SQL数据库基本操作
  12. GetLastError错误码
  13. Nacos一致性协议 CP/AP/JRaft/Distro协议
  14. Prometheus 四种metric类型
  15. c++ QT 反走样
  16. Python常用英文单词
  17. Fitbit与JMDC签订协议,指定JMDC为日本企业客户的Fitbit Premium独家分销商
  18. Cobaltstrike简介、安装及简单使用
  19. 5G时代来临,前端开发工程师必须了解的音视频入门基础知识
  20. 2021中国膳食纤维大会暨第八届中国膳食纤维产业大会

热门文章

  1. [译]Razor内幕之介绍
  2. 拆解百度自动驾驶最新动作:Apollo企业版和Apollo 3.5里的生意经和新风向 | CES 2019...
  3. PostgreSQL GPU 加速(HeteroDB pg_strom) (GPU计算, GPU-DIO-Nvme SSD, 列存, GPU内存缓存)
  4. 2018-03-28 Linux学习
  5. [转帖]成为合格系统管理员的标准
  6. 双十一虽过,李宁老师视频课程优惠仍将继续
  7. HTML5程序开发范例宝典(韩旭著)读书笔记之渐变背景
  8. Hive与数据库的异同
  9. Ibatis2.0使用说明(二)——配置篇(2)
  10. ASP.NET CORE的Code Fist后Models更改了怎么办?