LA 5031 图询问
题目链接: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 图询问相关推荐
- 浅谈分布式系统一致性之3PC协议
一.写在前面 分布式系统一致性专题本期该写 3PC 协议了,上周太忙没有时间更新,就拿了之前的旧文章做了一些调整重发了一下,还望各位读者海涵. 后面大约还有3期:Paxos 协议.Raft 协议等,先 ...
- MAX9814高性能麦克风
卓大大您好,我想问一下.我这里红色圈住的部分功能是什么,我仿真的时候加入这部分,给我一种模电里滤波的感觉? ▲ CSDN中实验电路(带有错误) 你的感觉是对的.我又重新看了一下你发送过来的这张图, ...
- (转)使用vsphere client 克隆虚拟机
使用vsphere client 克隆虚拟机 分类: linux2012-10-29 16:59 292人阅读 评论(0) 收藏 举报 免费的VMWare ESXi5.0非常强大,于是在vSphere ...
- 虚拟化之vmware-vsphere (web) client
两种客户端 vsphere client 配置>软件>高级设置里的变量 uservars.supressshellwarning=1 vsphere web client 安装完vSphe ...
- android studio linux 字体,Android Studio代码字体模糊解决方法
HDU3394:Railway 传送门 点双练习. 对于一张图,询问有多少条边不属于任意一个点双和多少条边至少属于两个点双. 显然,一张图里有多少个桥就是第一问的答案. 对于第二问,考虑对于一个点双, ...
- UIPower交互设计 - 《UI的革命》文字版
演讲者:UIPower用户体验部部长 陆国新博士 <UI的革命>第二部:<交互设计>,共分五讲: 第一讲:<交互设计的成功要素>视频地址:http://www.tu ...
- 虚拟服务器的克隆,使用vsphere client 克隆虚拟机的具体操作步骤(图文教程)
随着虚拟机的大量使用,用户在使用过程中也会遇到一些疑问和问题,正睿服务器作为Vmware的合作伙伴,今天就来与大家分享一下使用VSphere Client克隆虚拟机的知识. 用户疑问:采用 VMWar ...
- 【天池月饼活动】基于自然语言处理文本生成与轮询问答与依图生文与中秋月饼配图
文章目录 活动要求 项目演示 自然语言处理文本生成之对联上下联对答: 自然语言处理文本生成之依图生文: 多级轮询月饼对话 自动生成月饼 代码讲解 自从我前天进入阿里天池实验室,我就被他吸粉了,嫖了他的 ...
- 【Linux编程】一、Linux常见指令和权限理解(思维导图总结)
文章目录 Linux下基本指令 01.ls 指令 02.pwd 指令 03 cd 指令 04.mkdir 指令 05.rmdir 指令 06.rm 指令 07.tree 指令 08.cp 指令 09. ...
最新文章
- HAL Flat Display Driver Demystified
- Android O限制系统全屏进一步遏制手机勒索
- Kotlin 和Spring WebFlux
- sql 之as(Aliases)别名(mysql)
- 男科医生到底有多不正经… | 今日最佳
- laravel 导出插件
- 2.4 1死锁的概念(1)
- Pandas入门教程(一)
- python mpi4py 读取json_mpi4py 点到点通信总结
- [从零开始学习FPGA编程-27]:进阶篇 - 基本组合电路-数据比较器(Verilog语言)
- My SQL数据库基本操作
- GetLastError错误码
- Nacos一致性协议 CP/AP/JRaft/Distro协议
- Prometheus 四种metric类型
- c++ QT 反走样
- Python常用英文单词
- Fitbit与JMDC签订协议,指定JMDC为日本企业客户的Fitbit Premium独家分销商
- Cobaltstrike简介、安装及简单使用
- 5G时代来临,前端开发工程师必须了解的音视频入门基础知识
- 2021中国膳食纤维大会暨第八届中国膳食纤维产业大会
热门文章
- [译]Razor内幕之介绍
- 拆解百度自动驾驶最新动作:Apollo企业版和Apollo 3.5里的生意经和新风向 | CES 2019...
- PostgreSQL GPU 加速(HeteroDB pg_strom) (GPU计算, GPU-DIO-Nvme SSD, 列存, GPU内存缓存)
- 2018-03-28 Linux学习
- [转帖]成为合格系统管理员的标准
- 双十一虽过,李宁老师视频课程优惠仍将继续
- HTML5程序开发范例宝典(韩旭著)读书笔记之渐变背景
- Hive与数据库的异同
- Ibatis2.0使用说明(二)——配置篇(2)
- ASP.NET CORE的Code Fist后Models更改了怎么办?