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个 ...
随机推荐
- android开发之service详解
service作为android的四大组件之一,其重要性可想而知,在开发中,我们经常把一些不需要与用户进行交互的工作放在service中来完成,service运行在后台,这样有些人可能会产生错觉,以为 ...
- Nuget 相关
1:服务器搭建 1.1:创建空的Web Application 1.2:引用NuGet.Server 包:NuGet.Server 安装完成后的界面 web.config 已经被重写了,里面存在一些配 ...
- Use StringBuilder instead of String as possible as you can.
If you are care a littile about the time your algorithm cost,you should notice that,you my use Strin ...
- [转载]CentOS6.4+Mono3.0.7+Jexus5.2.5
本文章来自互联网,但是本人已经在VM虚拟机里面测试成功,所以分享给大家 1.更新 yum -y update 2.安装Mono源码安装需要的库 yum -y install gcc gcc-c++ a ...
- 玩转CSLA.NET小技巧系列一:跳转页面丢失session,如何解决
很少写代码,最近在写代码被登录难倒了,这丫的一直在跟我较劲 每次登录完跳转到首页后还是未登录状态 if (ModelState.IsValid) { bool isSuccess = FI.Finan ...
- 【转载】一步一步搭建自己的iOS网络请求库
一步一步搭建自己的iOS网络请求库(一) 大家好,我是LastDay,很久没有写博客了,这周会分享一个的HTTP请求库的编写经验. 简单的介绍 介绍一下,NSURLSession是iOS7中新的网络接 ...
- Relative与Absolute组合使用
小伙伴们学习了绝对定位的方法:使用position:absolute可以实现被设置元素相对于浏览器(body)设置定位以后, 大家有没有想过可不可以相对于其它元素进行定位呢?答案是肯定的,当然可以.使 ...
- SQL三大范式
第一范式:确保每列的原子性. 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式. 例如:顾客表(姓名.编号.地址.……)其中"地址"列还可 ...
- javascript中的基本数据类型
在javascipt中有五大基本数据类型,列表如下: 1.数字 他们又又包括(正负整数,浮点数)十进制数,十六进制数与八进制数,指数和特殊数值NaN,(Infinity,-Infinity)正负无穷 ...
- java 按天创建文件夹
按天创建文件夹,也就是每天创建一个,适合上传文件服务使用,文件数量较多时可以按文件夹区分. public static final String FMT = "yyyy-MM-dd" ...