这是一道无比繁琐的题目
话说这道题使我第一次练dfs序,比较感动;
首先dfs序就是在dfs过程中按照访问的顺序给每个点标上两个“时间戳”
一个是第一次访问到点i时的时间戳c[i],一个是访问完以i为根时的时间戳cc[i]
根据c[i],我们就可以将树变成序列,并且以i为根的子树,是序列上连续的一段
当进行单点修改时,我们可以用树状数组前缀和维护树上的点到根路径上所有点的修改情况和;
比如当点i修改时(比如+1) 则w[c[i]]+1,w[cc[i]]-1
然后这道题显然是要在dfs序上套带修改的主席树,根据bzoj2588的经验我们很好解决这个问题
由于修改的点要离散化,已经离线了,干脆用lca-tarjan求lca好了
由于空间卡的比较严,所以我们不能直接树状数组+主席树
而要先把原树建成主席树,然后修改的时候新建一棵主席树,用树状数组+主席树解决

  1. const maxn=;
  2.  
  3. type node=record
  4. po,next:longint;
  5. end;
  6. link=record
  7. l,r,s:longint;
  8. end;
  9. point=record
  10. x,y,z:longint;
  11. end;
  12. qu=record
  13. num,loc,next:longint;
  14. end;
  15.  
  16. var tree:array[..] of link;
  17. q:array[..] of point;
  18. w:array[..] of node;
  19. que:array[..] of qu;
  20. v:array[..] of boolean;
  21. e:array[..] of longint;
  22. g,fa,an,loc,d1,d2,ph,h,cc,c,b:array[..] of longint;
  23. st:array[..,..] of longint;
  24. sa,a:array[..] of longint;
  25. j,k,t,tot,num,len,x,y,z,i,p,s,n,m:longint;
  26.  
  27. function lowbit(x:longint):longint;
  28. begin
  29. exit(x and (-x));
  30. end;
  31.  
  32. procedure update(x:longint);
  33. begin
  34. tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s;
  35. end;
  36.  
  37. procedure add(x,y:longint);
  38. begin
  39. inc(len);
  40. w[len].po:=y;
  41. w[len].next:=d1[x];
  42. d1[x]:=len;
  43. end;
  44.  
  45. procedure addq(x,y,z:longint);
  46. begin
  47. inc(num);
  48. que[num].num:=y;
  49. que[num].loc:=z;
  50. que[num].next:=d2[x];
  51. d2[x]:=num;
  52. end;
  53.  
  54. function find(x:longint):longint;
  55. var l,r,m:longint;
  56. begin
  57. l:=;
  58. r:=p;
  59. while l<=r do
  60. begin
  61. m:=(l+r) shr ;
  62. if sa[m]=x then exit(m);
  63. if sa[m]>x then r:=m- else l:=m+;
  64. end;
  65. end;
  66.  
  67. function getf(x:longint):longint;
  68. begin
  69. if a[x]<>x then a[x]:=getf(a[x]);
  70. exit(a[x]);
  71. end;
  72.  
  73. procedure dfs(x:longint);
  74. var i,y:longint;
  75. begin
  76. i:=d1[x];
  77. v[x]:=true;
  78. inc(tot);
  79. b[tot]:=x; //b表示序列上的点对应的树上的哪个点
  80. c[x]:=tot;
  81. while i<> do
  82. begin
  83. y:=w[i].po;
  84. if not v[y] then
  85. begin
  86. fa[y]:=x;
  87. dfs(y);
  88. a[y]:=x;
  89. end;
  90. i:=w[i].next;
  91. end;
  92. cc[x]:=tot;
  93. i:=d2[x];
  94. while i<> do
  95. begin
  96. y:=que[i].num;
  97. if v[y] and (an[que[i].loc]=) then //lca-tarjan
  98. an[que[i].loc]:=getf(y);
  99. i:=que[i].next;
  100. end;
  101. end;
  102.  
  103. procedure sort(l,r: longint);
  104. var i,j,x,y: longint;
  105. begin
  106. i:=l;
  107. j:=r;
  108. x:=a[(l+r) div ];
  109. repeat
  110. while a[i]<x do inc(i);
  111. while x<a[j] do dec(j);
  112. if not(i>j) then
  113. begin
  114. y:=a[i];
  115. a[i]:=a[j];
  116. a[j]:=y;
  117. inc(i);
  118. j:=j-;
  119. end;
  120. until i>j;
  121. if l<j then sort(l,j);
  122. if i<r then sort(i,r);
  123. end;
  124.  
  125. function build(l,r:longint):longint;
  126. var m,q:longint;
  127. begin
  128. inc(t);
  129. if l=r then exit(t)
  130. else begin
  131. q:=t;
  132. m:=(l+r) shr ;
  133. tree[q].l:=build(l,m);
  134. tree[q].r:=build(m+,r);
  135. exit(q);
  136. end;
  137. end;
  138.  
  139. function insert(last,x,l,r,z:longint):longint;
  140. var m,q:longint;
  141. begin
  142. inc(t);
  143. if l=r then
  144. begin
  145. tree[t].s:=tree[last].s+z;
  146. exit(t);
  147. end
  148. else begin
  149. m:=(l+r) shr ;
  150. q:=t;
  151. if x<=m then
  152. begin
  153. tree[q].r:=tree[last].r;
  154. last:=tree[last].l;
  155. tree[q].l:=insert(last,x,l,m,z);
  156. end
  157. else begin
  158. tree[q].l:=tree[last].l;
  159. last:=tree[last].r;
  160. tree[q].r:=insert(last,x,m+,r,z);
  161. end;
  162. update(q);
  163. exit(q);
  164. end;
  165. end;
  166.  
  167. procedure work(i,x,z:longint);
  168. begin
  169. while i<=n do //树状数组+主席树
  170. begin
  171. h[i]:=insert(h[i],x,,p,z);
  172. i:=i+lowbit(i);
  173. end;
  174. end;
  175.  
  176. procedure get(x,y:longint);
  177. var i:longint;
  178. begin
  179. e[y]:=;
  180. st[,y]:=ph[x];
  181. i:=x;
  182. while i> do
  183. begin
  184. if h[i]<> then
  185. begin
  186. inc(e[y]);
  187. st[e[y],y]:=h[i];
  188. end;
  189. i:=i-lowbit(i);
  190. end;
  191. end;
  192.  
  193. function sum:longint;
  194. var i,j:longint;
  195. begin
  196. sum:=;
  197. for j:= to do
  198. for i:= to e[j] do
  199. if (j<=) then
  200. sum:=sum+tree[tree[st[i,j]].r].s
  201. else sum:=sum-tree[tree[st[i,j]].r].s;//u,v路径上的情况为tree[u]+tree[v]-tree[lca(u,v)]-tree[fa[lca(u,v)]];
  202. end;
  203.  
  204. function getans(l,r,k:longint):longint;
  205. var m,s,i,j:longint;
  206. begin
  207. if l=r then exit(sa[l])
  208. else begin
  209. m:=(l+r) shr ;
  210. s:=sum;
  211. if s>=k then
  212. begin
  213. for j:= to do
  214. for i:= to e[j] do
  215. st[i,j]:=tree[st[i,j]].r;
  216. exit(getans(m+,r,k));
  217. end
  218. else begin
  219. k:=k-s;
  220. for j:= to do
  221. for i:= to e[j] do
  222. st[i,j]:=tree[st[i,j]].l;
  223. exit(getans(l,m,k));
  224. end;
  225. end;
  226. end;
  227.  
  228. begin
  229. readln(n,m);
  230. for i:= to n do
  231. begin
  232. read(g[i]);
  233. a[i]:=g[i];
  234. end;
  235. s:=n;
  236. for i:= to n- do
  237. begin
  238. readln(x,y);
  239. add(x,y);
  240. add(y,x);
  241. end;
  242.  
  243. for i:= to m do
  244. begin
  245. readln(q[i].z,q[i].x,q[i].y);
  246. if q[i].z= then
  247. begin
  248. inc(s);
  249. a[s]:=q[i].y;
  250. end
  251. else begin
  252. addq(q[i].x,q[i].y,i);
  253. addq(q[i].y,q[i].x,i);
  254. end;
  255. end;
  256. sort(,s);
  257. p:=;
  258. sa[]:=a[];
  259. for i:= to s do
  260. if a[i]<>a[i-] then //离散化
  261. begin
  262. inc(p);
  263. sa[p]:=a[i];
  264. end;
  265.  
  266. for i:= to n do
  267. a[i]:=i;
  268. dfs();
  269. t:=;
  270. h[]:=build(,p);
  271. ph[]:=h[];
  272. for i:= to n do
  273. begin
  274. loc[i]:=find(g[b[i]]);
  275. y:=fa[b[i]];
  276. ph[i]:=insert(ph[c[y]],loc[i],,p,); //建立未修改前的主席树
  277. end;
  278. for i:= to m do
  279. begin
  280. if q[i].z<> then
  281. begin
  282. z:=an[i];
  283. get(c[q[i].x],); //提取区间
  284. get(c[q[i].y],);
  285. get(c[z],);
  286. get(c[fa[z]],);
  287. s:=;
  288. for j:= to do
  289. begin
  290. for k:= to e[j] do
  291. if (j<=) then
  292. s:=s+tree[st[k,j]].s
  293. else s:=s-tree[st[k,j]].s;
  294. end;
  295. if s<q[i].z then writeln('invalid request!')
  296. else writeln(getans(,p,q[i].z));
  297. end
  298. else begin
  299. x:=q[i].x;
  300. work(c[x],loc[c[x]],-);
  301. work(cc[x]+,loc[c[x]],);
  302. loc[c[x]]:=find(q[i].y);
  303. work(c[x],loc[c[x]],);
  304. work(cc[x]+,loc[c[x]],-);
  305. end;
  306. end;
  307. end.

bzoj1146的更多相关文章

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

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

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

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

  3. 【BZOJ1146】网络管理(主席树,树状数组)

    [BZOJ1146]网络管理(主席树,树状数组) 题面 BZOJ权限题,洛谷题面 题解 树上带修改主席树 貌似和\(Count\ On\ A\ Tree\)那题很相似呀 只需要套上一个树状数组来维护修 ...

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

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

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

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

  6. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

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

  7. 【BZOJ-1146】网络管理Network DFS序 + 带修主席树

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3495  Solved: 1032[Submi ...

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

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

  9. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...

  10. 【BZOJ1146】【树链剖分+平衡树】网络管理Network

    Description M 公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 信网络.该网络的结构由N个 ...

随机推荐

  1. [转] npm命令概述

    PS:问题,nvm找不到正确的下载server NVM_NODEJS_ORG_MIRROR=http://nodejs.org/dist nvm ls-remote NVM_NODEJS_ORG_MI ...

  2. IIS7保存配置文件及导入、导出、备份、还原

    IIS6下想要保存配置,只需在图形界面下点右键保存即可,但windows 2008下的IIS7却没有这样的选项, IIS7的配置文件有好几个,在c:\windows\system32\inetsrv\ ...

  3. JS快速排序和去重

    JS的快速排序和JS去重在面试的时候问的挺多的.下面是我对快速排序的理解,和快速排序,去重的代码. 1.什么是快速排序? 第一步: 快速排序就是去个中间值,把比中间值小的放在左边设为arrLeft,比 ...

  4. JAVA学习笔记--二

    一.抽象类: 访问修饰符 abstract class 类名{ } 抽象类和普通类的区别: 1. 抽象类不能被实例化 2. 抽象类一般含有抽象方法 抽象方法:在抽象类中只有方法签名(方法声明),没有方 ...

  5. 那些年,我们一起学WCF--(6)PerCall实例行为

    当客户端调用服务器端服务后,服务器端就会为客户端生成一个实例,关于服务实例的分配问题,在WCF中有专门的属性进行设置,可以让所有客户端共享一个实例, 也可以让一个客户端可以拥有多个实例,也可以让一个实 ...

  6. CentOS 7设置iptables防火墙开放proftpd端口

    由于ftp的被动模式是这样的,客户端跟服务器端的21号端口交互信令,服务器端开启21号端口能够使客户端登录以及查看目录.但是ftp被动模式用于传输数据的端口却不是21,而是大于1024的随机或配置文件 ...

  7. Linux系统swap已分区但无法挂载与cryptswap1问题

    linux下察看swap分区大小的命令 top 或者fdisk -l 或者free -m SWAP分区一般大小为物理内存的2倍,但最大不超过2G; 增加SWAP空间的方法有两个:增加另外一个SWAP分 ...

  8. Oracle 10G强大的SQL优化工具:SQL Tuning Advisor

    p { margin-bottom: 0.25cm; direction: ltr; color: rgb(0, 0, 0); line-height: 120%; orphans: 2; widow ...

  9. 苹果开发 笔记(80)升级IOS 9 和 XCode 7 引起的问题记录

    原文: http://blog.csdn.net/hero82748274/article/details/48629461 问题一: 升级xcode 7最低的系统配置要求 升级了ios9 后使用 x ...

  10. [转]一个备份MySQL数据库的简单Shell脚本

    本文翻译自 iSystemAdmin 的 <A Simple Shell Script to Backup MySQL Database> Shell脚本是我们写不同类型命令的一种脚本,这 ...