这是一道无比繁琐的题目
话说这道题使我第一次练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好了
由于空间卡的比较严,所以我们不能直接树状数组+主席树
而要先把原树建成主席树,然后修改的时候新建一棵主席树,用树状数组+主席树解决

 const maxn=;

 type node=record
po,next:longint;
end;
link=record
l,r,s:longint;
end;
point=record
x,y,z:longint;
end;
qu=record
num,loc,next:longint;
end; var tree:array[..] of link;
q:array[..] of point;
w:array[..] of node;
que:array[..] of qu;
v:array[..] of boolean;
e:array[..] of longint;
g,fa,an,loc,d1,d2,ph,h,cc,c,b:array[..] of longint;
st:array[..,..] of longint;
sa,a:array[..] of longint;
j,k,t,tot,num,len,x,y,z,i,p,s,n,m:longint; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; procedure update(x:longint);
begin
tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s;
end; procedure add(x,y:longint);
begin
inc(len);
w[len].po:=y;
w[len].next:=d1[x];
d1[x]:=len;
end; procedure addq(x,y,z:longint);
begin
inc(num);
que[num].num:=y;
que[num].loc:=z;
que[num].next:=d2[x];
d2[x]:=num;
end; function find(x:longint):longint;
var l,r,m:longint;
begin
l:=;
r:=p;
while l<=r do
begin
m:=(l+r) shr ;
if sa[m]=x then exit(m);
if sa[m]>x then r:=m- else l:=m+;
end;
end; function getf(x:longint):longint;
begin
if a[x]<>x then a[x]:=getf(a[x]);
exit(a[x]);
end; procedure dfs(x:longint);
var i,y:longint;
begin
i:=d1[x];
v[x]:=true;
inc(tot);
b[tot]:=x; //b表示序列上的点对应的树上的哪个点
c[x]:=tot;
while i<> do
begin
y:=w[i].po;
if not v[y] then
begin
fa[y]:=x;
dfs(y);
a[y]:=x;
end;
i:=w[i].next;
end;
cc[x]:=tot;
i:=d2[x];
while i<> do
begin
y:=que[i].num;
if v[y] and (an[que[i].loc]=) then //lca-tarjan
an[que[i].loc]:=getf(y);
i:=que[i].next;
end;
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function build(l,r:longint):longint;
var m,q:longint;
begin
inc(t);
if l=r then exit(t)
else begin
q:=t;
m:=(l+r) shr ;
tree[q].l:=build(l,m);
tree[q].r:=build(m+,r);
exit(q);
end;
end; function insert(last,x,l,r,z:longint):longint;
var m,q:longint;
begin
inc(t);
if l=r then
begin
tree[t].s:=tree[last].s+z;
exit(t);
end
else begin
m:=(l+r) shr ;
q:=t;
if x<=m then
begin
tree[q].r:=tree[last].r;
last:=tree[last].l;
tree[q].l:=insert(last,x,l,m,z);
end
else begin
tree[q].l:=tree[last].l;
last:=tree[last].r;
tree[q].r:=insert(last,x,m+,r,z);
end;
update(q);
exit(q);
end;
end; procedure work(i,x,z:longint);
begin
while i<=n do //树状数组+主席树
begin
h[i]:=insert(h[i],x,,p,z);
i:=i+lowbit(i);
end;
end; procedure get(x,y:longint);
var i:longint;
begin
e[y]:=;
st[,y]:=ph[x];
i:=x;
while i> do
begin
if h[i]<> then
begin
inc(e[y]);
st[e[y],y]:=h[i];
end;
i:=i-lowbit(i);
end;
end; function sum:longint;
var i,j:longint;
begin
sum:=;
for j:= to do
for i:= to e[j] do
if (j<=) then
sum:=sum+tree[tree[st[i,j]].r].s
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)]];
end; function getans(l,r,k:longint):longint;
var m,s,i,j:longint;
begin
if l=r then exit(sa[l])
else begin
m:=(l+r) shr ;
s:=sum;
if s>=k then
begin
for j:= to do
for i:= to e[j] do
st[i,j]:=tree[st[i,j]].r;
exit(getans(m+,r,k));
end
else begin
k:=k-s;
for j:= to do
for i:= to e[j] do
st[i,j]:=tree[st[i,j]].l;
exit(getans(l,m,k));
end;
end;
end; begin
readln(n,m);
for i:= to n do
begin
read(g[i]);
a[i]:=g[i];
end;
s:=n;
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end; for i:= to m do
begin
readln(q[i].z,q[i].x,q[i].y);
if q[i].z= then
begin
inc(s);
a[s]:=q[i].y;
end
else begin
addq(q[i].x,q[i].y,i);
addq(q[i].y,q[i].x,i);
end;
end;
sort(,s);
p:=;
sa[]:=a[];
for i:= to s do
if a[i]<>a[i-] then //离散化
begin
inc(p);
sa[p]:=a[i];
end; for i:= to n do
a[i]:=i;
dfs();
t:=;
h[]:=build(,p);
ph[]:=h[];
for i:= to n do
begin
loc[i]:=find(g[b[i]]);
y:=fa[b[i]];
ph[i]:=insert(ph[c[y]],loc[i],,p,); //建立未修改前的主席树
end;
for i:= to m do
begin
if q[i].z<> then
begin
z:=an[i];
get(c[q[i].x],); //提取区间
get(c[q[i].y],);
get(c[z],);
get(c[fa[z]],);
s:=;
for j:= to do
begin
for k:= to e[j] do
if (j<=) then
s:=s+tree[st[k,j]].s
else s:=s-tree[st[k,j]].s;
end;
if s<q[i].z then writeln('invalid request!')
else writeln(getans(,p,q[i].z));
end
else begin
x:=q[i].x;
work(c[x],loc[c[x]],-);
work(cc[x]+,loc[c[x]],);
loc[c[x]]:=find(q[i].y);
work(c[x],loc[c[x]],);
work(cc[x]+,loc[c[x]],-);
end;
end;
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. Oracler读取各种格式的相关日期格式

    CREATE OR REPLACE Package Pkg_Stm_Date As     --Purpose:相关日期处理功能包          --获取某一天是第几周     Function ...

  2. 使用WebSocket构建实时WEB

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3795075.html ...

  3. Java_Activiti5_菜鸟也来学Activiti5工作流_之与Spring集成(三)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  4. php生成不重复随机字符串

    使用时间戳作为原始字符串,再随机生成五个字符随机插入任意位置,生成新的字符串,保证不重复 function rand($len) { $chars='ABCDEFGHIJKLMNOPQRSTUVWXY ...

  5. java 基本类型和包装类的比较

    public class BoxingTest { @Test public void test1(){ String a = new String("1"); String b ...

  6. dnw for linux: Ubuntu下可用,无需编译驱动,mini2440可用

    1.安装所需库文件 sudo apt-get install libusb-dev 2.源代码如下 /* dnw2 linux main file. This depends on libusb. * ...

  7. innerHTML/outerHTML; innerText/outerText; textContent

    innerHTML v.s. outerHTML Element.innerHTML Reference: https://developer.mozilla.org/en-US/docs/Web/A ...

  8. asp.net将数据导出到excel

    本次应用datatable导出,若用gridview(假设gridview设为了分页显示)会出现只导出当前页的情况. protected void btnPrn_Click(object sender ...

  9. 利用set实现去重

    最近读了一些有关于ES6的文章,觉得真是一个超级大的进步,就是不知道兼容性怎么样,鉴于我还在初学,先写个小例子练手,顺便时刻提醒自己要坚持学下去.未来的趋势肯定是替代es5没跑了. var arr=[ ...

  10. devicePixelRatio

    devicePixelRatio window.devicePixelRatio是设备上物理像素和逻辑像素的比例.公式表示就是:window.devicePixelRatio = 物理像素 / 逻辑像 ...