【BZOJ2733】永无乡[HNOI2012](splay启发式合并or线段树合并)
题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点。题目中给定的是每个节点的排名,所以实际上是求第k小;题目求的是编号,不是重要度的排名。我一开始差点被这坑了。
网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733
这道题似乎挺经典的(至少我看许多神犇很早就做了这道题)。这道题有两种写法:并查集+(splay启发式合并or线段树合并)。我写的是线段树合并,因为……splay不会打+懒得学。
线段树合并具体可以看ppt:https://wenku.baidu.com/view/88f4e134e518964bcf847c95.html(线段树的合并——杭州二中黄嘉泰)
这道题可以一开始每个节点建一棵值域线段树(没用到的子树像trie一样,先指向null),然后合并操作就用上面文章中线段树合并的方法,同时把并查集合并一下(如果把树x合并到树y,那么在并查集里也要把fa[x]改为y,这样就能保证并查集的根和线段树的根是同一个节点),查询可以先用并查集查出这个节点属于哪棵树,然后在树上二分(就是在值域线段树上求序列第k大),然后就完了。
P.S.似乎不加读入优化我的线段树合并要比我一位同学的splay快400ms+,不过splay很常用,还是过几天学一学吧。。。(第一行是我加了快读的线段树合并,第二行没有加快读,第三行是同学的splay)
奇丑无比的代码:
- #include<cstdio>
- using namespace std;
- struct hh{
- int lc,rc,sum;
- }a[];
- int rank[],id[],fa[],tot;
- int read()
- {
- char c=getchar(),flag=;
- while(c<''||''<c){
- if(c=='-')flag=-; c=getchar();
- }
- int tmp=;
- while(''<=c&&c<=''){
- tmp=tmp*+c-''; c=getchar();
- }
- return tmp*flag;
- }
- void add(int now,int x,int l,int r)
- {
- ++a[now].sum; if(l==r)return;
- if(x<=(l+r)>>){
- if(!a[now].lc)a[now].lc=++tot;
- add(a[now].lc,x,l,(l+r)>>);
- }
- else{
- if(!a[now].rc)a[now].rc=++tot;
- add(a[now].rc,x,((l+r)>>)+,r);
- }
- }
- int query(int now,int x,int l,int r)
- {
- if(l==r)return l;
- if(a[a[now].lc].sum>=x)return query(a[now].lc,x,l,(l+r)>>);
- else return query(a[now].rc,x-a[a[now].lc].sum,((l+r)>>)+,r);
- }
- void merge(int x,int y)
- {
- a[x].sum+=a[y].sum;
- if(a[x].lc||a[x].rc){
- if(a[y].lc){
- if(!a[x].lc)a[x].lc=a[y].lc;
- else merge(a[x].lc,a[y].lc);
- }
- if(a[y].rc){
- if(!a[x].rc)a[x].rc=a[y].rc;
- else merge(a[x].rc,a[y].rc);
- }
- }
- }
- int find(int x)
- {
- if(fa[x]==x)return x;
- return fa[x]=find(fa[x]);
- }
- int main()
- {
- int n=read(),m=read(),i; tot=n;
- for(i=;i<=n;i++){
- rank[i]=read(); id[rank[i]]=fa[i]=i;
- add(i,rank[i],,n);
- }
- for(i=;i<=m;i++){
- int x=read(),y=read(),fx,fy;
- fx=find(x); fy=find(y);
- if(fx!=fy){
- fa[fy]=fx; merge(fx,fy);
- }
- }
- m=read();
- for(i=;i<=m;i++){
- char ch; scanf("%s",&ch);
- int x=read(),y=read();
- if(ch=='Q'){
- int fx=find(x);
- if(a[fx].sum<y)printf("-1\n"); else printf("%d\n",id[query(fx,y,,n)]);
- }
- else{
- int fx=find(x),fy=find(y);
- if(fx!=fy){
- fa[fy]=fx; merge(fx,fy);
- }
- }
- }
- }
splay的等学了再补吧。。。
【BZOJ2733】永无乡[HNOI2012](splay启发式合并or线段树合并)的更多相关文章
- BZOJ2733 永无乡【splay启发式合并】
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ2733 永无乡 【splay启发式合并】
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 4190 Solved: 2226 [Submit][Sta ...
- 【HNOI2012】永无乡 题解(并查集+线段树合并)
题目链接 给定一张含$n$个点$m$条边的无向图,每个点有一个重要指数$a_i$.有两种操作:1.在$x$和$y$之间连一条边:2.求$x$所在连通块中重要程度第$k$小的点. ----------- ...
- bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)
这题之前写过线段树合并,今天复习Splay的时候想起这题,打算写一次Splay+启发式合并. 好爽!!! 写了长长的代码(其实也不长),只凭着下午的一点记忆(没背板子...),调了好久好久,过了样例, ...
- Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3955 Solved: 2112[Submit][Statu ...
- 【题解】永无乡 [HNOI2012] [BZOJ2733] [P3224]
[题解]永无乡 [HNOI2012] [BZOJ2733] [P3224] [题目描述] 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要 ...
- 【HNOI2012】永无乡(splay,启发式合并)
题解 Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过 ...
- bzoj2733 永无乡 splay树的启发式合并
https://vjudge.net/problem/HYSBZ-2733 给一些带权点,有些点是互相连通的, 然后给出2种操作,在两点间加一条边,或者询问一个点所在的连通块内的第k小值的编号 并查集 ...
- [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并
好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...
随机推荐
- Android错误——基础篇
1. Android工程在真机上运行调试: 花了二个小时的时间来把App热部署到小米机上,简直让我寒透了心, 原本是按照网上提供的步骤一步步的做着,没想到小米神机居然出的是什么内测小米助手,两个窗口来 ...
- 深入理解IEnumerable和IQueryable两接口的区别
from:http://blog.csdn.net/ydm19891101/article/details/50969323 无论是在ado.net EF或者是在其他的Linq使用中,我们经常会碰到两 ...
- iOS提交到appstore的新要求
本文转载至http://blog.csdn.net/kqygww/article/details/41277555 64-bit and iOS 8 Requirements for New ...
- Cocos2d-x Lua中网格动作
GridAction它有两个主要的子类Grid3DAction和TiledGrid3DAction,TiledGrid3DAction系列的子类中会有瓦片效果,如下图所示是Waves3D特效(Grid ...
- git commit -a -m "DM 1、获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传;"
git commit -a -m "DM 1.获取aliOssSTS值,计算签名,实现视频PUT/POST2种上传方式上传:" 微信小程序的视频上传
- a database of all existing files
mlocate.db(5): mlocate database - Linux man page https://linux.die.net/man/5/mlocate.db Name mlocat ...
- <2013 12 01> 一篇很好的关于windows编程的入门指导(2013年末写的,比较前沿)
我之前做了不少嵌入式开发,从单片机到ARM到RTOS到Linux等等,可以说走的是电气工程师的路线,对编程也是实用性的,跟计算机学院的科班套路不同.最近同学做一个windowsCE的项目请我帮忙,之前 ...
- BaseServlet 介绍
1. BaseServlet 的作用 让一个Servlet可以处理多种不同的请求,不同的请求调用Servlet的不同方法. 2. 实现原理 客户端发送请求时, 必须多给出一个参数, 用来说明要调用的方 ...
- LOJ#2230. 「BJOI2014」大融合
LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...
- Django 模板系统(template)
介绍 官方文档 常用模板语法 只需要记两种特殊符号: {{ }} 和 {% %} 变量相关的用{{}} 逻辑相关的用{%%} 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模 ...