Description

在一片古老的土地上,有一个繁荣的文明。
这片大地几乎被森林覆盖,有N座城坐落其中。巧合的是,这N座城由恰好N-1条双
向道路连接起来,使得任意两座城都是连通的。也就是说,这些城形成了树的结构,任意两
座城之间有且仅有一条简单路径。
在这个文明中,骑士是尤其受到尊崇的职业。任何一名骑士,都是其家族乃至家乡的荣
耀。Henry从小就渴望成为一名能守护家乡、驱逐敌人的骑士。勤奋训练许多年后,Henry
终于满18岁了。他决定离开家乡,向那些成名已久的骑士们发起挑战!
根据Henry的调查,大陆上一共有M名受封骑士,不妨编号为1到M。
第i个骑士居住在城Pi,武力值为Fi。
Henry计划进行若干次旅行,每次从某座城出发沿着唯一的简单路径前往另一座城,
同时会挑战路线上武力值最高的K个骑士(Henry的体力有限,为了提高水平,当然要挑
战最强的骑士)。如果路线上的骑士不足K人,Henry会挑战遇到的所有人。
每次旅行前,可能会有某些骑士的武力值或定居地发生变化,Henry自然会打听消息,
并对计划做出调整。
为了在每次旅行时做好充分准备,Henry希望你能帮忙在每次旅行前计算出这条路线
上他将挑战哪些对手。

Input

第一行,一个整数N,表示有N座城,编号为1~N。
接下来N-1行,每行两个整数Ui和Vi,表示城Ui和城Vi之间有一条道路相连。
第N+1行,一个整数M,表示有M个骑士。
接下来M行,每行两个整数Fi和Pi。按顺序依次表示编号为1~M的每名骑士的武
力值和居住地。
第N+M+2行,两个整数Q,K,分别表示操作次数和每次旅行挑战的骑士数目上限。
接下来Q行,每行三个整数Ti,Xi,Yi。Ti取值范围为{1,2,3},表示操作类型。
一共有以下三种类型的操作:
Ti=1时表示一次旅行,Henry将从城Xi出发前往城市Yi;
Ti=2时表示编号为Xi的骑士的居住地搬到城Yi;
Ti=3时表示编号为Xi的骑士的武力值修正为Yi。

Output

输出若干行,依次为每个旅行的答案。
对每个Ti=1的询问,输出一行,按从大到小的顺序输出Henry在这次旅行中挑战的
所有骑士的武力值。如果路线上没有骑士,输出一行,为一个整数-1。
对每个点用multiset维护点权,树链剖分+线段树维护区间上前k大的数(降序),对于查询可以把对应的区间提取出来用堆维护一下多路归并求出前k大
单次查询时间复杂度约为O((log^2(n)+k)log(log^2(n))),修改为O(klogn)
  1. #include<bits/stdc++.h>
  2. const int N=;
  3. char buf[N*],*ptr=buf-;
  4. int _(){
  5. int x=,c=*++ptr;
  6. while(c<)c=*++ptr;
  7. while(c>)x=x*+c-,c=*++ptr;
  8. return x;
  9. }
  10. int n,m,q,k;
  11. int es[N*],enx[N*],e0[N],ep=;
  12. std::multiset<int,std::greater<int> >vs[N];
  13. int as[N],bs[N];
  14. int fa[N],sz[N],son[N],dep[N],top[N],id[N],idr[N],idp=;
  15. int _l,_r,*Q[N],qp;
  16. bool cmp(int*a,int*b){
  17. return *a<*b;
  18. }
  19. void push(int*a){
  20. Q[qp++]=a;
  21. std::push_heap(Q,Q+qp,cmp);
  22. }
  23. struct node{
  24. node*lc,*rc,*f;
  25. int L,R;
  26. int v[];
  27. void init(int x){
  28. int p=;
  29. for(std::multiset<int>::iterator it=vs[x].begin();p<k&&it!=vs[x].end();v[p++]=*(it++));
  30. for(;p<k;v[p++]=-);
  31. }
  32. void up(){
  33. int p=,p1=,p2=,*v1=lc->v,*v2=rc->v;
  34. while(p<k&&p1<k&&p2<k)v[p++]=v1[p1]>v2[p2]?v1[p1++]:v2[p2++];
  35. while(p<k&&p1<k)v[p++]=v1[p1++];
  36. while(p<k&&p2<k)v[p++]=v2[p2++];
  37. }
  38. void upds(){
  39. for(node*w=f;w;w->up(),w=w->f);
  40. }
  41. void get(){
  42. if(_l<=L&&R<=_r){
  43. if(~v[])push(v);
  44. return;
  45. }
  46. int M=L+R>>;
  47. if(_l<=M)lc->get();
  48. if(_r>M)rc->get();
  49. }
  50. }ns[N*],*np=ns,*rt[N],*pos[N];
  51. node*build(int L,int R){
  52. node*w=np++;
  53. w->L=L;w->R=R;
  54. memset(w->v,-,sizeof(w->v));
  55. if(L!=R){
  56. int M=L+R>>;
  57. (w->lc=build(L,M))->f=
  58. (w->rc=build(M+,R))->f=w;
  59. w->up();
  60. }else{
  61. pos[idr[L]]=w;
  62. w->init(idr[L]);
  63. }
  64. return w;
  65. }
  66. void f1(int w,int pa){
  67. dep[w]=dep[fa[w]=pa]+;
  68. sz[w]=;
  69. for(int i=e0[w];i;i=enx[i]){
  70. int u=es[i];
  71. if(u!=pa){
  72. f1(u,w);
  73. sz[w]+=sz[u];
  74. if(sz[u]>sz[son[w]])son[w]=u;
  75. }
  76. }
  77. }
  78. void f2(int w,int tp){
  79. top[w]=tp;
  80. idr[id[w]=++idp]=w;
  81. if(son[w])f2(son[w],tp);
  82. else rt[tp]=build(id[tp],id[w]);
  83. for(int i=e0[w];i;i=enx[i]){
  84. int u=es[i];
  85. if(u!=fa[w]&&u!=son[w])f2(u,u);
  86. }
  87. }
  88. int main(){
  89. buf[fread(buf,,sizeof(buf),stdin)]=;
  90. n=_();
  91. for(int i=,a,b;i<n;++i){
  92. a=_();b=_();
  93. es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
  94. es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
  95. }
  96. m=_();
  97. for(int i=;i<=m;++i){
  98. as[i]=_();bs[i]=_();
  99. vs[bs[i]].insert(as[i]);
  100. }
  101. q=_();k=_();
  102. f1(,);f2(,);
  103. for(int i=,o,x,y;i<q;++i){
  104. o=_();x=_();y=_();
  105. if(o==){
  106. qp=;
  107. int a=top[x],b=top[y];
  108. while(a!=b){
  109. if(dep[a]<dep[b])std::swap(x,y),std::swap(a,b);
  110. _l=id[a],_r=id[x],rt[a]->get();
  111. x=fa[a];a=top[x];
  112. }
  113. if(dep[x]>dep[y])std::swap(x,y);
  114. _l=id[x],_r=id[y],rt[top[x]]->get();
  115. if(!qp)printf("-1");
  116. for(int j=;j<k&&qp;++j){
  117. int*p=Q[];
  118. std::pop_heap(Q,Q+qp--,cmp);
  119. printf("%d ",*p);
  120. if(~*++p)push(p);
  121. }
  122. putchar();
  123. }else if(o==){
  124. vs[bs[x]].erase(vs[bs[x]].find(as[x]));
  125. pos[bs[x]]->init(bs[x]);
  126. pos[bs[x]]->upds();
  127. vs[bs[x]=y].insert(as[x]);
  128. pos[bs[x]]->init(bs[x]);
  129. pos[bs[x]]->upds();
  130. }else{
  131. vs[bs[x]].erase(vs[bs[x]].find(as[x]));
  132. vs[bs[x]].insert(as[x]=y);
  133. pos[bs[x]]->init(bs[x]);
  134. pos[bs[x]]->upds();
  135. }
  136. }
  137. return ;
  138. }

bzoj4336: BJOI2015 骑士的旅行的更多相关文章

  1. [BZOj4336][BJOI2015]骑士的旅行(树链剖分+线段树)

    树链剖分,对每个叶子用multiset记录前K大士兵,其余节点通过从儿子归并维护前K大士兵.过于模板. #include<set> #include<cstdio> #incl ...

  2. 【vijos】1791 骑士的旅行(特殊的技巧)

    https://vijos.org/p/1791 暴力的话只想到bfs,然后估计是状态超了才得20分. 噗,为啥暴力就不能想得简单点QAQ.....这种思想很好啊. 这一题我看了题解后不得不说我竟然没 ...

  3. 刷题总结——骑士的旅行(bzoj4336 树链剖分套权值线段树)

    题目: Description 在一片古老的土地上,有一个繁荣的文明. 这片大地几乎被森林覆盖,有N座城坐落其中.巧合的是,这N座城由恰好N-1条双 向道路连接起来,使得任意两座城都是连通的.也就是说 ...

  4. bzoj4336 骑士的旅行 (树链剖分+multiset)

    首先大概有一个树剖+树套树的做法,但我哪会写啊 然后发现k很小,如果用线段树记每个区间前k大的的话,可以O(k)地合并 而且一个点还有可能有好多个骑士,所以要用multiset维护一下 然后树剖就好啦 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. poj2488 A Knight's Journey

    http://poj.org/problem?id=2488 题目大意:骑士厌倦了一遍又一遍地看到同样的黑白方块,于是决定去旅行. 世界各地.当一个骑士移动时,他走的是“日”字.骑士的世界是他赖以生存 ...

  7. 小结:bfs

    概要: 我们在初始状态要到达终止状态可以沿着同深度的向下搜索,这样范围覆盖更广,在解的深度较小的时候十分适用. 技巧及注意: 所有状态在转移后如果要打标记一定要在进队列前打!不要在出队列才打!否则就是 ...

  8. [BFS]骑士旅行

    骑士旅行 Description 在一个n m 格子的棋盘上,有一只国际象棋的骑士在棋盘的左下角 (1;1)(如图1),骑士只能根据象棋的规则进行移动,要么横向跳动一格纵向跳动两格,要么纵向跳动一格横 ...

  9. 【BZOJ4704】旅行 树链剖分+可持久化线段树

    [BZOJ4704]旅行 Description 在Berland,有n个城堡.每个城堡恰好属于一个领主.不同的城堡属于不同的领主.在所有领主中有一个是国王,其他的每个领主都直接隶属于另一位领主,并且 ...

随机推荐

  1. Nginx+keepalived 脚本安装主从双机热备自动切换解决方案

    Nginx+keepalived 脚本安装主从双机热备自动切换解决方案 2013-07-02 19:24:13 标签:filesnginx keepalived 原创作品,允许转载,转载时请务必以超链 ...

  2. C++中几个值得分析的小问题(2)

    下面有3个小问题,作为C++ Beginner你一定要知道错在哪里了. 1.派生类到基类的引用或指针转换一定“完美”存在? 一般情况,你很可能会认为:派生类对象的引用或指针转换为基类对象的引用或指针是 ...

  3. New Concept English three(10)

    The great ship, Titanic, sailed for New York from Southampton on April 10th, 1912. She was carrying ...

  4. Jquery如何获取ASP.NET服务器控件的值

    关键字: Jquery 服务器控件 获取值 由于ASP.NET网页运行后,服务器控件会随机生成客户端id,jquery获取时候不太好操作,总结有以下3种方法:   服务器控件代码:<asp:Te ...

  5. jQuery选项卡wdScrollTab

    实例Demo 运行一下 参数说明 Config active Number   Active tab index. Base on 0. autoResizable Boolean   Whether ...

  6. Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件

    Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件 前面我写了一篇博文Shell 从日志文件中选择时间段内的日志输出到另一个文件,利用循环实现了我想要实现的内容. 但是用这个脚本的同 ...

  7. CBUS转MQTT

    CBUS转MQTT,楼宇控制协议通过迈思德网关转MQTT

  8. Elasticsearch安装配置和测试

    官方教程:https://www.elastic.co/guide/en/elasticsearch/reference/master/_installation.html 中文教程:https:// ...

  9. iOS开发-UITextView文字排版

    UITextView文本排版 1.配置NSMutableParagraphStyle NSMutableParagraphStyle *MParaStyle = [[NSMutableParagrap ...

  10. Andriod4.2 Camera 架构与实现

    1.Camera架构包括客户端和服务端,他们之间的通信采用Binder机制实现. Camera的实现主要包括本地代码和Java代码两个层次: Camera本地框架: frameworks/native ...