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 ...
随机推荐
- bzoj1002:[FJOI2007]轮状病毒
思路:一道很裸的生成树计数问题,然而要高精度,而且听说直接行列式求值会被卡精度,所以可以模拟行列式求值的过程得到递推公式:f[i]=3*f[i-1]-f[i-2]+2,证明详见vfk博客: http: ...
- python 安装mysql 客户端遇到的问题
一. Win7 64位编译Python扩展解决”error: Unable to find vcvarsall.bat”问题 系统上安装有Visual Studio 2010以及相应的SDK,然后 ...
- [翻译][MVC 5 + EF 6] 12[完结]:高级场景
原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 1.执行原生SQL查询: EF Code First API ...
- leetcode problem 33 -- Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- el-get
el-get Table of Contents 1. 依赖 2. 安装 3. 配置 3.1. 自定义包配置 4. 命令 5. 管理扩展 el-get 是一个emacs下的扩展管理工具.就像apt-g ...
- WPF中实现根据拼音查找汉字
1.WPF的一个触摸屏项目,需要输入姓名,但是屏幕不支持汉字输入,使用虚拟键盘不稳定,为了解决该问题特此进行处理. 2.新建一个类转换类,里面初始化一个数组,数组包含拼音,以及拼音下的常用的汉字. 3 ...
- Centos7 设置IPtables
entOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop firewalld.service #停止fire ...
- POJ1182并查集
食物链 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物, ...
- 我写了个教程《一步步教你把ubuntu安装到U盘》
一步步教你把ubuntu安装到U盘 作者 Val 2452013147@qq.com 原因: 由于某些原因(学生党),需要把ubuntu安装到U盘到处走,百度了一下,教程都不是很好,要么很复杂,要么不 ...
- Python设计模式——设计原则
1.单一职责原则:每个类都只有一个职责,修改一个类的理由只有一个 2.开放-封闭远程(OCP):开放是指可拓展性好,封闭是指一旦一个类写好了,就尽量不要修改里面的代码,通过拓展(继承,重写等)来使旧的 ...