题意:树上单点修改,询问链上k大值。

思路:

1.DFS序+树状数组套主席树

首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息。

关于询问,就是Que(u)+Que(v)-Que(LCA(u,v))-Que(father(LCA(u,v))),线段树上二分查询第k大即可。

考虑修改,修改一个点影响到的点为它子树中的所有点,所以要用DFS序。于是这实际上是区间修改单点询问的问题,外面套一层主席树即可。

$O(n\log^2 n)$

2.二分+树链剖分+线段树套平衡树

由于是链上询问,考虑树链剖分。首先二分答案mid,然后问题转化为求mid在这条链上的排名,在树链上用线段树维护,每棵树中维护一棵平衡树,用来求排名。

$O(n\log^4 n)$理论上会超但实际上常数比较小。

第一种码力太弱码不出来,写了第二种,速度OJ上倒数(空间倒是十分优秀)。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define ls (x<<1)
  5. #define rs (ls|1)
  6. #define lson ls,L,mid
  7. #define rson rs,mid+1,R
  8. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  9. #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
  10. using namespace std;
  11.  
  12. const int N=,M=;
  13. bool vis[N];
  14. int n,Q,cnt,tot,nd,tmp,tim,ans,u,v;
  15. int val[M],lc[M],rc[M],hp[M],sz[M],w[M];
  16. int T[N],pos[N],b[N<<],fa[N],son[N],dep[N],top[N],root[N<<];
  17. int h[N],to[N<<],nxt[N<<];
  18. struct Que{ int k,a,b; }q[N];
  19.  
  20. void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
  21.  
  22. void dfs1(int x){
  23. sz[x]=;
  24. For(i,x) if ((k=to[i])!=fa[x]){
  25. fa[k]=x; dep[k]=dep[x]+; dfs1(k); sz[x]+=sz[k];
  26. if (sz[k]>sz[son[x]]) son[x]=k;
  27. }
  28. }
  29.  
  30. void dfs2(int x,int tp){
  31. top[x]=tp; pos[x]=++tim;
  32. if (son[x]) dfs2(son[x],tp);
  33. For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
  34. }
  35.  
  36. int lca(int u,int v){
  37. for (; top[u]!=top[v]; u=fa[top[u]])
  38. if (dep[top[u]]<dep[top[v]]) swap(u,v);
  39. return (dep[u]<dep[v]) ? u : v;
  40. }
  41.  
  42. void rrot(int &x){
  43. int y=lc[x]; lc[x]=rc[y]; rc[y]=x;
  44. sz[y]=sz[x]; sz[x]=sz[lc[x]]+sz[rc[x]]+w[x]; x=y;
  45. }
  46.  
  47. void lrot(int &x){
  48. int y=rc[x]; rc[x]=lc[y]; lc[y]=x;
  49. sz[y]=sz[x]; sz[x]=sz[lc[x]]+sz[rc[x]]+w[x]; x=y;
  50. }
  51.  
  52. void ins(int &x,int k){
  53. if (!x) { x=++nd; sz[x]=w[x]=; hp[x]=rand(); val[x]=k; return; }
  54. sz[x]++;
  55. if (k==val[x]) { w[x]++; return; }
  56. if (k<val[x]){ ins(lc[x],k); if (hp[lc[x]]<hp[x]) rrot(x); }
  57. else{ ins(rc[x],k); if (hp[rc[x]]<hp[x]) lrot(x); }
  58. }
  59.  
  60. void del(int &x,int k){
  61. if (val[x]==k){
  62. if (w[x]>) { sz[x]--; w[x]--; return; }
  63. if (!lc[x] || !rc[x]) { x=lc[x]+rc[x]; return; }
  64. if (hp[lc[x]]<hp[rc[x]]) rrot(x),del(x,k);
  65. else lrot(x),del(x,k);
  66. return;
  67. }
  68. sz[x]--;
  69. if (k<val[x]) del(lc[x],k); else del(rc[x],k);
  70. }
  71.  
  72. void getrank(int x,int k){
  73. if (!x) return;
  74. if (val[x]==k) tmp+=sz[rc[x]];
  75. else if (k>val[x]) getrank(rc[x],k); else tmp+=sz[rc[x]]+w[x],getrank(lc[x],k);
  76. }
  77.  
  78. void mdf(int x,int L,int R,int pos,int a,int b){
  79. if (~a) del(root[x],a); ins(root[x],b);
  80. if (L==R) return;
  81. int mid=(L+R)>>;
  82. if (pos<=mid) mdf(lson,pos,a,b); else mdf(rson,pos,a,b);
  83. }
  84.  
  85. void que(int x,int L,int R,int l,int r,int k){
  86. if (L==l && r==R){ getrank(root[x],k); return; }
  87. int mid=(L+R)>>;
  88. if (r<=mid) que(lson,l,r,k);
  89. else if (l>mid) que(rson,l,r,k);
  90. else que(lson,l,mid,k),que(rson,mid+,r,k);
  91. }
  92.  
  93. void Get(int x,int f,int k){
  94. while (top[x]!=top[f]) que(,,n,pos[top[x]],pos[x],k),x=fa[top[x]];
  95. que(,,n,pos[f],pos[x],k);
  96. }
  97.  
  98. void solve(int x,int y,int k){
  99. int t=lca(x,y); ans=-;
  100. if (dep[x]+dep[y]-dep[t]-dep[fa[t]]<k){ puts("invalid request!"); return; }
  101. int L=,R=tot;
  102. while (L<=R){
  103. int mid=(L+R)>>;
  104. tmp=; Get(x,t,mid); Get(y,t,mid);
  105. if (T[t]>mid) tmp--;
  106. if (tmp<k) R=mid-,ans=mid; else L=mid+;
  107. }
  108. printf("%d\n",b[ans]);
  109. }
  110.  
  111. int main(){
  112. freopen("bzoj1146.in","r",stdin);
  113. freopen("bzoj1146.out","w",stdout);
  114. scanf("%d%d",&n,&Q);
  115. rep(i,,n) scanf("%d",&T[i]),b[++tot]=T[i];
  116. rep(i,,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
  117. dep[]=; dfs1(); dfs2(,);
  118. rep(i,,Q){
  119. scanf("%d%d%d",&q[i].k,&q[i].a,&q[i].b);
  120. if (!q[i].k) b[++tot]=q[i].b;
  121. }
  122. sort(b+,b+tot+); tot=unique(b+,b+tot+)-b-;
  123. rep(i,,n) T[i]=lower_bound(b+,b+tot+,T[i])-b;
  124. rep(i,,Q) if (!q[i].k) q[i].b=lower_bound(b+,b+tot+,q[i].b)-b;
  125. rep(i,,n) mdf(,,n,pos[i],-,T[i]);
  126. rep(i,,Q)
  127. if (!q[i].k) mdf(,,n,pos[q[i].a],T[q[i].a],q[i].b),T[q[i].a]=q[i].b;
  128. else solve(q[i].a,q[i].b,q[i].k);
  129. return ;
  130. }

[BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)的更多相关文章

  1. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  2. 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分

    题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...

  3. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  4. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  5. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  6. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  7. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

随机推荐

  1. POJ2912:Rochambeau(带权并查集)

    Rochambeau Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5208   Accepted: 1778 题目链接:h ...

  2. angular的一些问题

    引入第三方类库 1.安装依赖 npm install jquey --save 2.引入项目 在angular-cli.json "scripts": [ "../nod ...

  3. codeforces 1065D

    题目链接:https://codeforces.com/problemset/problem/1065/D 题意:给你一个又1~n^2组成的n行n列的矩阵,你可以走日字型,直线,斜线,现在要求你从1走 ...

  4. 毕业答辩的PPT攻略

    关于内容: 1.一般概括性内容:课题标题.答辩人.课题执行时间.课题指导教师.课题的归属.致谢等.  2.课题研究内容:研究目的.方案设计(流程图).运行过程.研究结果.创新性.应用价值.有关课题延续 ...

  5. 定时导出用户数据(expdp,impdp)

    一 定时导出数据: #!/bin/bash############################################################################### ...

  6. node读取文件夹名

    const fs = require('fs'); const join = require('path').join; /** * * @param startPath 起始目录文件夹路径 * @r ...

  7. 转:Spring-session & redis 子域名共享session

    Spring-session & redis 子域名共享session 例子: a.example.com b.example.com spring 版本 4.2.6.RELEASE Spri ...

  8. 设计模式功能概述(Design Patterns)

    1.Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 2.Adapter:将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于 ...

  9. 【Foreign】哈密顿回路 [MIM]

    哈密顿回路 Time Limit: 15 Sec  Memory Limit: 256 MB Description Input Output Sample Input 4 10 0 3 2 1 3 ...

  10. 【BZOJ】1708: [Usaco2007 Oct]Money奶牛的硬币

    [算法]DP [题解] 如果每个排列算一种,则令f[i]表示凑成面值为i的方案数,容易推出f[i]+=f[i-a[j]]. 现在是每个组合才算一种,令f[i][j]第二维表示只使用前j种面值,f[i] ...