传送门

题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值。


思路:

读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值。

那么这个题把树状数组放到树上用树链剖分维护一下即可。

代码:

  1. #include<bits/stdc++.h>
  2. #define ri register int
  3. using namespace std;
  4. inline int read(){
  5. int ans=0;
  6. char ch=getchar();
  7. while(!isdigit(ch))ch=getchar();
  8. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  9. return ans;
  10. }
  11. const int N=8e4+5;
  12. int n,m,a[N],siz[N],hson[N],fa[N],dep[N],top[N],num[N],pred[N],bit[N],ans[N],tot=0,sig=0,Q=0;
  13. vector<int>e[N];
  14. struct Node{int k,a,b,id;}q[N*3],qtmp1[N*3],qtmp2[N*3];
  15. inline int lowbit(int x){return x&-x;}
  16. inline void update(int x,int v){for(ri i=x;i<=n;i+=lowbit(i))bit[i]+=v;}
  17. inline int query(int x){int ret=0;for(ri i=x;i;i-=lowbit(i))ret+=bit[i];return ret;}
  18. void dfs1(int p){
  19. siz[p]=1;
  20. for(ri i=0,v;i<e[p].size();++i){
  21. if((v=e[p][i])==fa[p])continue;
  22. fa[v]=p,dep[v]=dep[p]+1,dfs1(v),siz[p]+=siz[v];
  23. if(siz[v]>siz[hson[p]])hson[p]=v;
  24. }
  25. }
  26. void dfs2(int p,int tp){
  27. top[p]=tp,pred[num[p]=++tot]=p;
  28. if(!hson[p])return;
  29. dfs2(hson[p],tp);
  30. for(ri i=0,v;i<e[p].size();++i)if((v=e[p][i])!=fa[p]&&v!=hson[p])dfs2(v,v);
  31. }
  32. inline int lca(int x,int y){
  33. while(top[x]^top[y]){
  34. if(dep[top[x]]<dep[top[y]])swap(x,y);
  35. x=fa[top[x]];
  36. }
  37. return dep[x]<dep[y]?x:y;
  38. }
  39. inline int dist(int a,int b){return dep[a]+dep[b]-2*dep[lca(a,b)]+1;}
  40. inline int ask(int x,int y){
  41. int ret=0;
  42. while(top[x]^top[y]){
  43. if(dep[top[x]]<dep[top[y]])swap(x,y);
  44. ret+=query(num[x])-query(num[top[x]]-1),x=fa[top[x]];
  45. }
  46. if(dep[x]<dep[y])swap(x,y);
  47. return ret+query(num[x])-query(num[y]-1);
  48. }
  49. inline void solve(int ql,int qr,int vl,int vr){
  50. if(ql>qr)return;
  51. if(vl==vr){for(ri i=ql;i<=qr;++i)if(q[i].k&&~ans[q[i].id])ans[q[i].id]=vl;return;}
  52. int mid=vl+vr>>1,hd1=0,hd2=0;
  53. for(ri i=ql;i<=qr;++i){
  54. if(!q[i].k){
  55. if(q[i].b<=mid)qtmp1[++hd1]=q[i];
  56. else qtmp2[++hd2]=q[i],update(num[q[i].a],q[i].id);
  57. }
  58. else{
  59. int ret=ask(q[i].a,q[i].b);
  60. if(ret>=q[i].k)qtmp2[++hd2]=q[i];
  61. else q[i].k-=ret,qtmp1[++hd1]=q[i];
  62. }
  63. }
  64. for(ri i=ql;i<=qr;++i)if(!q[i].k&&q[i].b>mid)update(num[q[i].a],-q[i].id);
  65. for(ri i=1;i<=hd1;++i)q[ql+i-1]=qtmp1[i];
  66. for(ri i=1;i<=hd2;++i)q[ql+hd1+i-1]=qtmp2[i];
  67. solve(ql,ql+hd1-1,vl,mid),solve(ql+hd1,qr,mid+1,vr);
  68. }
  69. int main(){
  70. n=read(),m=read();
  71. for(ri i=1;i<=n;++i)q[++sig]=(Node){0,i,a[i]=read(),1};
  72. for(ri i=1,u,v;i<n;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
  73. dfs1(1),dfs2(1,1);
  74. for(ri i=1,k,x,y;i<=m;++i){
  75. k=read(),x=read(),y=read();
  76. if(!k){
  77. q[++sig]=(Node){k,x,a[x],-1};
  78. q[++sig]=(Node){k,x,a[x]=y,1};
  79. }
  80. else{
  81. ++Q;
  82. int dis=dist(x,y);
  83. if(dis<k)ans[Q]=-1;
  84. q[++sig]=(Node){k,x,y,Q};
  85. }
  86. }
  87. solve(1,sig,1,100000000);
  88. for(ri i=1;i<=Q;++i){
  89. if(~ans[i])cout<<ans[i]<<'\n';
  90. else puts("invalid request!");
  91. }
  92. return 0;
  93. }

2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)的更多相关文章

  1. [CTSC2008]网络管理(整体二分+树剖+树状数组)

    一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...

  2. [BZOJ1146][CTSC2008]网络管理Network

    [BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...

  3. 【BZOJ1146】网络管理(整体二分)

    [BZOJ1146]网络管理(整体二分) 题面 良心洛谷,有BZOJ权限题 题解 要看树套树的戳这里 毕竟是:智商不够数据结构来补 所以, 我们来当一回智商够的选手 听说主席树的题目大部分都可以整体二 ...

  4. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  5. 2019.01.14 bzoj5343: [Ctsc2018]混合果汁(整体二分+权值线段树)

    传送门 整体二分好题. 题意简述:nnn种果汁,每种有三个属性:美味度,单位体积价格,购买体积上限. 现在有mmm个询问,每次问能否混合出总体积大于某个值,总价格小于某个值的果汁,如果能,求所有方案中 ...

  6. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  7. BZOJ1146——[CTSC2008]网络管理Network

    1.题目大意:就是在动态的树上路径权值第k大. 2.分析:这个就是树链剖分+树套树 #include <cstdio> #include <cstdlib> #include ...

  8. 【树上莫队】【带修莫队】【权值分块】bzoj1146 [CTSC2008]网络管理Network

    #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using ...

  9. 【树链剖分】【函数式权值分块】bzoj1146 [CTSC2008]网络管理Network

    裸题,直接上.复杂度O(n*sqrt(n)*log(n)). //Num[i]表示树中的点i在函数式权值分块中对应的点 //Map[i]表示函数式权值分块中的点i在树中对应的点 #include< ...

随机推荐

  1. 线程 Thread Handler

    new Thread(new Runnable() { @Override public void run() { Message msg = new Message(); msg.what = 0; ...

  2. 前端框架(kraken、Express、Node、MVC)

    You know my loneliness is only kept for you, my sweet songs are only sang for you. 前端框架相关知识记录. krake ...

  3. 微信小程序开发——使用回调函数出现异常:TypeError: Cannot read property 'setData' of undefined

    关键技术点: 作用域问题——回调函数中的作用域已经脱离了调用函数了,因此需要在回调函数外边把this赋给一个新的变量才可以了. 业务需求: 微信小程序开发,业务逻辑需要,需要把获取手机号码的业务逻辑作 ...

  4. POJ 1177 Picture(线段树周长并)

      描述 A number of rectangular posters, photographs and other pictures of the same shape are pasted on ...

  5. Quartz代码及配置详解(转)

    Quartz可以用来做什么? Quartz是一个任务调度框架.比如你遇到这样的问题 想每月25号,信用卡自动还款 想每年4月1日自己给当年暗恋女神发一封匿名贺卡 想每隔1小时,备份一下自己的爱情动作片 ...

  6. linux命令学习之:mv

    mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 命令格式    mv [选项] 源文件或目 ...

  7. MySQL在windows的my-default.ini配置

    my-default.ini分为两块:Client Section和Server Section. Client Section用来配置MySQL客户端参数. 要查看配置参数可以用下面的命令: sho ...

  8. supervisor安装、使用详解

    supervisor是用python写的一个进程管理工具,用来启动,重启,关闭进程. 1 supervisor的安装 pip install supervisor 2 supervisor的配置文件( ...

  9. Kafka基本使用

    Kafka基本使用 官网地址  http://kafka.apache.org/   一切应以官网文档为准. 安装 download里下载要安装的版本.或者直接wget该网址.如wget http:/ ...

  10. JavaScript 练习题

    练习题 1. 使用for循环输出1到50的值,要求每次循环只能输出一个值,每输出十个换一行. 2 日历生成器: 要求 用户输入,这个月有多少天,本月1号是星期几,自动生成日历 3. 表格生成器 4.  ...