B20J_2733_[HNOI2012]永无乡_权值线段树合并

Description:

n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛。现在有两种操作:B x y表示在岛 x与岛y之间修建一座新桥。Q x k表示询问当前与岛 x连通的所有岛中第k重要的是哪座岛,即所有与岛 x连通的岛中重要度排名第 k小的岛是哪座,请你输出那个岛的编号。

对于100%的数据n≤100000,m≤n,q≤300000。

分析:读懂题后发现是一道线段树合并的裸题。Q操作显然是权值线段树求区间第k小元素,B操作是合并。

直接开发现开不下,需要动态开点,一开始要开nlogn个结点。

合并操作:

  1. int merge(int x,int y)
  2. {
  3. if(!x)return y;
  4. if(!y)return x;
  5. lson[x]=merge(lson[x],lson[y]);
  6. rson[x]=merge(rson[x],rson[y]);
  7. t[x]=t[lson[x]]+t[rson[x]];
  8. return x;
  9. }

代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N=3262145;
  6. int tree[N],lson[N],rson[N],t[N],mp[N],fa[N],idx[N],cnt;
  7. int n,m,k;
  8. char s[10];
  9. int find(int x)
  10. {
  11. return fa[x]==x?x:fa[x]=find(fa[x]);
  12. }
  13. void bt(int l,int r,int val,int &pos)
  14. {
  15. if(pos==0)pos=++cnt;
  16. if(l==r)
  17. {
  18. t[pos]=1;
  19. return ;
  20. }
  21. int mid=l+r>>1;
  22. if(val<=mid)bt(l,mid,val,lson[pos]);
  23. else bt(mid+1,r,val,rson[pos]);
  24. t[pos]=t[lson[pos]]+t[rson[pos]];
  25. }
  26. int merge(int x,int y)
  27. {
  28. if(!x)return y;
  29. if(!y)return x;
  30. lson[x]=merge(lson[x],lson[y]);
  31. rson[x]=merge(rson[x],rson[y]);
  32. t[x]=t[lson[x]]+t[rson[x]];
  33. return x;
  34. }
  35. int query(int l,int r,int k,int pos)
  36. {
  37. if(l==r||k==0)
  38. {
  39. return mp[l];
  40. }
  41. int mid=l+r>>1;
  42. if(t[pos]<k)return -1;
  43. if(t[lson[pos]]>=k)
  44. {
  45. return query(l,mid,k,lson[pos]);
  46. }
  47. else
  48. {
  49. return query(mid+1,r,k-t[lson[pos]],rson[pos]);
  50. }
  51. }
  52. int main()
  53. {
  54. scanf("%d%d",&n,&m);
  55. for(int i=1;i<=n;i++)
  56. {
  57. fa[i]=i;
  58. }
  59. for(int i=1;i<=n;i++)
  60. {
  61. scanf("%d",&idx[i]);
  62. mp[idx[i]]=i;
  63. }
  64. for(int i=1;i<=n;i++)
  65. {
  66. tree[i]=++cnt;
  67. bt(1,n,idx[i],tree[i]);
  68. }
  69. int x,y;
  70. for(int i=1;i<=m;i++)
  71. {
  72. scanf("%d%d",&x,&y);
  73. int dx=find(x),dy=find(y);
  74. if(dx!=dy)
  75. {
  76. fa[dy]=dx;
  77. tree[dx]=merge(tree[dx],tree[dy]);
  78. }
  79. }
  80. scanf("%d",&k);
  81. while(k--)
  82. {
  83. scanf("%s%d%d",s,&x,&y);
  84. int dx=find(x);
  85. if(s[0]=='Q')
  86. {
  87. printf("%d\n",query(1,n,y,tree[dx]));
  88. }
  89. else
  90. {
  91. int dx=find(x),dy=find(y);
  92. if(dx!=dy)
  93. {
  94. fa[dy]=dx;
  95. tree[dx]=merge(tree[dx],tree[dy]);
  96. }
  97. }
  98. }
  99. }

B20J_2733_[HNOI2012]永无乡_权值线段树合并的更多相关文章

  1. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  2. BZOJ2733 [HNOI2012]永无乡(并查集+线段树合并)

    题目大意: 在$n$个带权点上维护两个操作: 1)在点$u,v$间连一条边: 2)询问点$u$所在联通块中权值第$k$小的点的编号,若该联通块中的点的数目小于$k$,则输出$-1$: 传送门 上周的模 ...

  3. luogu3224 永无乡(动态开点,权值线段树合并)

    luogu3224 永无乡(动态开点,权值线段树合并) 永无乡包含 n 座岛,编号从 1 到 n ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 n 座岛排名,名次用 1 到 n 来表示.某些 ...

  4. BZOJ_2161_布娃娃_权值线段树

    BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...

  5. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

  6. BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树

    BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资. ...

  7. 【bzoj1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+权值线段树合并

    题目描述 求一张图的严格次小生成树的边权和,保证存在. 输入 第一行包含两个整数N 和M,表示无向图的点数与边数. 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z ...

  8. 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并

    题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...

  9. 【bzoj2212】[Poi2011]Tree Rotations 权值线段树合并

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tr ...

随机推荐

  1. 没人看系列-----html随笔

    <!DOCTYPE> 目录 没人看系列-----html/css详解 前言 不多说这段时间写了好多好多前端的东西,以至于自己重新返回看了一遍前端的所有技术.故此做个总结,准备学东西的请绕行 ...

  2. No plugin found for prefix 'tomcat' in the current project and in the plugin groups和java.net.BindException: Address already in use: JVM_Bind <null>:8080的错误解决

    错误报告:No plugin found for prefix 'tomcat' in the current project and in the plugin groups [org.apache ...

  3. python---购物车---更新

    购物车程序更新: 更新商家入口,实现以下功能: 1. 商家能够修改商品价格: 2. 商家能够下线商品: 3. 商家能够增加商品: 4. 商品信息存在文件中 # -*- coding:utf-8 -*- ...

  4. 装修工人如何在网上"找活"

    http://blog.sina.com.cn/s/blog_555e8fe80102wwsz.html ps:其实码农也是一种装修工. 在这个互联网时代,各个行业都在利用网络达到自己的商业目的,作为 ...

  5. Resin4下JSP文件导出问题的解决

           之前我在Resin3下采用JSP代码对一些硬盘上的文件作读取以后再输出或者生成一些特殊格式文件(如Excel)再输出供下载,这些文件输出JSP代码在Resin4以后输出的文件都产生错误无 ...

  6. .net core2.0添加json文件并转化成类注入控制器使用

    上一篇,我们介绍了如何读取自定义的json文件,数据是读取出来了,只是处理的时候太麻烦,需要一遍一遍写,很枯燥.那么有没有很好的办法呢?经过钻研,办法有了. 既然一个一个读取比较麻烦,那么可以把它放入 ...

  7. Python3实现ICMP远控后门(上)_补充篇

    ICMP后门(上)补充篇 前言 在上一篇文章Python3实现ICMP远控后门(上)中,我简要讲解了ICMP协议,以及实现了一个简单的ping功能,在文章发表之后,后台很多朋友留言,说对校验和的计算不 ...

  8. Linux的安装(虚拟机环境)与基础配置

    一.背景 本文介绍如何安装虚拟机VMware以及如果在虚拟机上安装Linux系统以及Linux安装完毕之后的基础配置 需要准备的东西有VMware以及Linux镜像文件 二.下载安装VMware 下载 ...

  9. Reactor三种线程模型与Netty线程模型

    文中所讲基本都是以非阻塞IO.异步IO为基础.对于阻塞式IO,下面的编程模型几乎都不适用 Reactor三种线程模型 单线程模型 单个线程以非阻塞IO或事件IO处理所有IO事件,包括连接.读.写.异常 ...

  10. [CVPR2017] Deep Self-Taught Learning for Weakly Supervised Object Localization 论文笔记

    http://openaccess.thecvf.com/content_cvpr_2017/papers/Jie_Deep_Self-Taught_Learning_CVPR_2017_paper. ...