bzoj1146
这是一道无比繁琐的题目
话说这道题使我第一次练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的更多相关文章
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- 【BZOJ1146】网络管理(整体二分)
[BZOJ1146]网络管理(整体二分) 题面 良心洛谷,有BZOJ权限题 题解 要看树套树的戳这里 毕竟是:智商不够数据结构来补 所以, 我们来当一回智商够的选手 听说主席树的题目大部分都可以整体二 ...
- 【BZOJ1146】网络管理(主席树,树状数组)
[BZOJ1146]网络管理(主席树,树状数组) 题面 BZOJ权限题,洛谷题面 题解 树上带修改主席树 貌似和\(Count\ On\ A\ Tree\)那题很相似呀 只需要套上一个树状数组来维护修 ...
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
- BZOJ1146——[CTSC2008]网络管理Network
1.题目大意:就是在动态的树上路径权值第k大. 2.分析:这个就是树链剖分+树套树 #include <cstdio> #include <cstdlib> #include ...
- bzoj1146整体二分+树链剖分+树状数组
其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...
- 【BZOJ1146】【树链剖分+平衡树】网络管理Network
Description M 公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 信网络.该网络的结构由N个 ...
随机推荐
- 隐藏iframe边框
关于iframe在ie浏览器中边框隐藏的问题,一直困惑着我.其实就是一个很简单的办法,主要设置一个属性即可解决,方法如下: <iframe frameborder="0"&g ...
- 洛谷比赛 堕落的Joe
/*暴力50*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100010 ...
- U3D 背景音效和事件触发音效
首先,想要在一个游戏添加背景音乐其实很简单,就是利用一个组件 就能够实现音频的播放,不过要实现通过某一个事件,来进行声音的播放,比如跳跃啊什么的: public AudioClip jumpclips ...
- CSS Clip剪切元素实例
一.实例1: .fixed { position: fixed; width: 382px; height: 100px; background: red; border: 1px solid blu ...
- HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket
一.单文件上传实例 HTML: <div class="container"> <div class="panel panel-default" ...
- vs2013下的WCFRest 模板开发WCF
在vs2013下使用wcfRestservice40 是安装不成功的,尝试多遍,都是这样.查看以前vs2012做的wcfrest,经过调教,终于在vs2013下也可以了! 1.新建wcf服务应用程序 ...
- WCF存储图片到指定文件夹下
string path = System.IO.Directory.GetCurrentDirectory() + @"\POIImages\"; Guid imgid = Gui ...
- Android 新版NDK环境搭建(免Cygwin)
使用最新ndk,直接抛弃cygwin,以前做Android的项目要用到NDK就必须要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配 ...
- SGU 134.Centroid(图心)
SGU链接: 时间限制:0.25s 空间限制:4M 题意: 给出一个树(节点数<=16000),一个节点的重量定义为从树中去除这个点后,新得到的所有树中节点最多的树的节点数.树的中心定义为所有节 ...
- 寒假挑战PythonTip(一人一python)总结——算法是程序的灵魂,程序员的心法
2014年2月中旬,我上升到挑战python英雄榜第3名.这是我寒假修炼算法的成果之一.来一下总结吧! Linux的创始人Linus Torvalds在一次演讲中有一段涉及“什么才是优秀程序员 ...