bzoj3626
百度空间马上要下架的说,赶快把最后一点题解补完,然后搬家
这是一道不错的题,首先注意询问是满足区间减法的,我们把他变成前缀和表示
设我们询问[1,r]中的点和z的LCA深度和,假设我们确定一个根,不难发现一个有趣的事情
点z和点i的LCA深度=z和i到根公共路径(LCA到根的路径)上点的个数!
也就是说,当我们查询时,我们只要知道,[1,r]上的点到根路径上的点在z到根上出现的次数和
所以不难想到离线的做法,按照编号的顺序,每次做到点i,就把点i到根路径上点权值+1
询问的时候我们只要查询z到根路径上点权值和即可,显然我们可以用树链剖分+线段树维护
const mo=;
type node=record
po,next:longint;
end;
que=record
x,y,p,op:longint;
end; var p,c,top,ans,fa,size:array[..] of longint;
tree,lazy:array[..*] of longint;
q:array[..] of que;
e:array[..] of node;
t,l,r,x,i,j,n,m:longint; procedure swap(var a,b:que);
var c:que;
begin
c:=a;
a:=b;
b:=c;
end; procedure add(x,y:longint);
begin
e[i].po:=y;
e[i].next:=p[x];
p[x]:=i;
end; procedure dfs1(x:longint);
var i,y:longint;
begin
size[x]:=;
i:=p[x];
while i<> do
begin
y:=e[i].po;
fa[y]:=x;
dfs1(y);
size[x]:=size[x]+size[y];
i:=e[i].next;
end;
end; procedure dfs2(x:longint);
var i,y,q:longint;
begin
inc(t);
c[x]:=t;
q:=n+;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if size[y]>size[q] then q:=y;
i:=e[i].next;
end;
if q<>n+ then
begin
top[q]:=top[x];
dfs2(q);
end;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if y<>q then
begin
top[y]:=y;
dfs2(y);
end;
i:=e[i].next;
end;
end; procedure sort(l,r:longint);
var i,j,y:longint;
begin
i:=l;
j:=r;
y:=q[(l+r) shr ].y;
repeat
while q[i].y<y do inc(i);
while y<q[j].y do dec(j);
if not(i>j) then
begin
swap(q[i],q[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure push(i,l,r:longint);
var m:longint;
begin
m:=(l+r) shr ;
tree[i*]:=tree[i*]+lazy[i]*(m+-l);
tree[i*+]:=tree[i*+]+lazy[i]*(r-m);
inc(lazy[i*],lazy[i]);
inc(lazy[i*+],lazy[i]);
lazy[i]:=;
end; procedure work(i,l,r,x,y:longint);
var m:longint;
begin
if (x<=l) and (y>=r) then
begin
tree[i]:=tree[i]+r-l+;
lazy[i]:=lazy[i]+;
end
else begin
if lazy[i]> then push(i,l,r);
m:=(l+r) shr ;
if x<=m then work(i*,l,m,x,y);
if y>m then work(i*+,m+,r,x,y);
tree[i]:=(tree[i*]+tree[i*+]) mod mo;
end;
end; function getans(i,l,r,x,y:longint):longint;
var m,s:longint;
begin
if (x<=l) and (y>=r) then exit(tree[i])
else begin
if lazy[i]> then push(i,l,r);
m:=(l+r) shr ;
s:=;
if x<=m then s:=s+getans(i*,l,m,x,y);
if y>m then s:=s+getans(i*+,m+,r,x,y);
exit(s);
end;
end; procedure ins(x:longint);
begin
while top[x]<>- do
begin
work(,,n,c[top[x]],c[x]);
x:=fa[top[x]];
end;
work(,,n,,c[x]);
end; function ask(x:longint):longint;
begin
ask:=;
while top[x]<>- do
begin
ask:=ask+getans(,,n,c[top[x]],c[x]);
x:=fa[top[x]];
end;
ask:=(ask+getans(,,n,,c[x])) mod mo;
end; begin
readln(n,m);
for i:= to n- do
begin
read(x);
add(x,i);
end;
dfs1();
top[]:=-;
dfs2();
t:=;
for i:= to m do
begin
readln(l,r,x);
inc(t);
q[t].x:=x; q[t].y:=l-;
q[t].p:=i; q[t].op:=-;
inc(t);
q[t].x:=x; q[t].y:=r;
q[t].p:=i; q[t].op:=;
end;
sort(,t);
j:=;
for i:= to t do
begin
while (j<n) and (j<=q[i].y) do
begin
ins(j);
inc(j);
end;
ans[q[i].p]:=(ans[q[i].p]+q[i].op*ask(q[i].x)+mo) mod mo;
end;
for i:= to m do
writeln(ans[i]);
end.
bzoj3626的更多相关文章
- bzoj3083 遥远的国度 && bzoj3626 LCA (树链剖分)
今早刷了两道树剖的题目,用时两小时十五分钟= = 树剖的题目代码量普遍120+ 其实打熟练之后是很容易调的,不熟练的话代码量大可能会因为某些小细节调很久 3083:裸树剖+"换根" ...
- 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)
[BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...
- 浅谈一类无关序列有前缀和性质的统计问题的离线解法 BZOJ3626
每次询问[l,r]区间,但所有信息是按另一种序列给出的,因此无法使用区间数据结构做这种题.将每个询问改为[1,x],考虑离线,则从1~n依次修改并查询即可. BZOJ3626 给定一颗树,每次询问给定 ...
- BZOJ3626 LNOI2014LCA(树链剖分+主席树)
开店简化版. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...
- BZOJ3626 [LNOI2014]LCA 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3626 题意概括 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节 ...
- 【BZOJ3626】[LNOI2014]LCA 离线+树链剖分+线段树
[BZOJ3626][LNOI2014]LCA Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度 ...
- 【BZOJ3626】LCA(树上差分,树链剖分)
题意:给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询问给 ...
- [BZOJ3626] [LNOI2014]LCA(树链剖分)
[BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...
- [bzoj3626][LNOI2014]LCA
Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...
- 【BZOJ-3626】LCA 树链剖分
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1428 Solved: 526[Submit][Status ...
随机推荐
- 懒人记录 Hadoop2.7.1 集群搭建过程
懒人记录 Hadoop2.7.1 集群搭建过程 2016-07-02 13:15:45 总结 除了配置hosts ,和免密码互连之外,先在一台机器上装好所有东西 配置好之后,拷贝虚拟机,配置hosts ...
- 学习C++ Primer 的个人理解(七)
类,后面还有两章是介绍有关于类的内容的.这一张依然只是个概括.但也已经将大致用法介绍完了. 重点如下: 1.成员函数的声明,必须在类的内部. 2.引用const成员函数 我们知道成员函数中有一个名为t ...
- [java学习笔记]JDK的安装和环境变量的配置
1.JDK的下载和安装 jdk(java development kit)是java提供给我们的一套java开发工具,它必运行在JVM(java虚拟机)上,java语言的跨平台性就是利用java运行在 ...
- php configure help
`configure' configures this package to adapt to many kinds of systems. Usage: ./configure [OPTION].. ...
- 【原创】开机出现grub rescue,修复办法
出现这种问题 一般在于进行了磁盘分区(GHOST备份时也会造成)导致grub引导文件找不到.我们只要让它找到引导文件就好了. 此时屏幕上提示grub resume> 我们先输入set看下现在g ...
- fuser 命令概述
fuser 概述 fuser命令是用来显示所有正在使用着指定的file, file system 或者 sockets的进程信息. 例一: #fuser –m –u /mnt/usb1 /mnt/us ...
- jQuery1.8以上,ajaxSend,ajaxStart等一系列事件要绑定在document上才有效果
jQuery1.8以上,ajaxSend,ajaxStart等一系列事件要绑定在document上才有效果
- Jqery之select操作
jquery获取select选择的文本与值 获取select : 获取select 选中的 text : $("#ddlregtype").find("optio ...
- 001.XE3添加TPerlRegEx
TPerlRegEx 官方下载地址:http://www.regular-expressions.info/download/TPerlRegEx.zip 下载解压,打开pcre.pas文件可看到,直 ...
- Python用format格式化字符串
format是是python2.6新增的一个格式化字符串的方法,相对于老版的%格式方法,它有很多优点. 1.不需要理会数据类型的问题,在%方法中%s只能替代字符串类型 2.单个参数可以多次输出,参数顺 ...