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 Activity横竖屏转换的生命周期
新创建一个Activity,用来此次测试. 先贴代码 package com.hugo.apj.activitylifetest; import android.support.v7.app.AppC ...
- Raphaël.js学习笔记
Rapheal.js 是一个矢量图绘图库.对于支持HTML5 SVG的浏览器使用SVG绘图,不支持SVG的IE(ie6,7,8)使用VML绘图.所以Raphael.js的兼容性非常好. Raphael ...
- 纯javascript代码编写计算器程序
今天来分享一下用纯javascript代码编写的一个计算器程序,很多行业都能用到这个程序,例如做装修预算.贷款利率等等. 首先来看一下完成后的效果: 具体代码如下:(关注我的博客,及时获取最新WEB前 ...
- 使用AutoMapper实现Dto和Model之间自由转换
应用场景:一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转 ...
- iOS单例的两种实现
单例模式算是开发中比较常见的一种模式了.在iOS中,单例有两种实现方式(至少我目前只发现两种).根据线程安全的实现来区分,一种是使用@synchronized,另一种是使用GCD的dispatch_o ...
- Visual Studio2010 安装msdn
1.注册VS2010 断网(不要冒险)->运行Microsoft Visual Studio 2010->帮助->注册产品->YCFHQ-9DWCY-DKV88-T2TMH-G ...
- BFC块级格式化上下文简述
做过页面编写的各位应该对定位不陌生了,这个样式表中的重头戏,也是最难把控的元素之一,今天在这里我们要讲到的就是与浮动与清除浮动相关的定位元素,对于定位有很多种,有绝对定位,还有相对定位,固定定位,静态 ...
- STL库list::sort()实现深度解析
原创,转载请注明出处:STL库list::sort()实现深度解析 list模板的定义以及一些基本成员函数的实现这里我就不赘述了,还不清楚的同学可以到网上查找相关资料或者直接查看侯捷翻译的<ST ...
- POJ 1236.Network of Schools (强连通)
首先要强连通缩点,统计新的图的各点的出度和入度. 第一问直接输出入度为0的点的个数 第二问是要是新的图变成一个强连通图,那么每一个点至少要有一条出边和一条入边,输出出度和入度为0的点数大的那一个 注意 ...
- 未能解析目标框架“.NETFramework,Version=v4.0”的 mscorlib 错误的解决办法
查看项目属性,发现该项目的目标框架是.NET Framework 4 Client Profile ,而被引用的程序集的目标框架是.NET Framework 4,将该项目的目标框架修改成.NET F ...