百度空间马上要下架的说,赶快把最后一点题解补完,然后搬家
这是一道不错的题,首先注意询问是满足区间减法的,我们把他变成前缀和表示
设我们询问[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的更多相关文章

  1. bzoj3083 遥远的国度 && bzoj3626 LCA (树链剖分)

    今早刷了两道树剖的题目,用时两小时十五分钟= = 树剖的题目代码量普遍120+ 其实打熟练之后是很容易调的,不熟练的话代码量大可能会因为某些小细节调很久 3083:裸树剖+"换根" ...

  2. 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)

    [BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...

  3. 浅谈一类无关序列有前缀和性质的统计问题的离线解法 BZOJ3626

    每次询问[l,r]区间,但所有信息是按另一种序列给出的,因此无法使用区间数据结构做这种题.将每个询问改为[1,x],考虑离线,则从1~n依次修改并查询即可. BZOJ3626 给定一颗树,每次询问给定 ...

  4. BZOJ3626 LNOI2014LCA(树链剖分+主席树)

    开店简化版. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  5. BZOJ3626 [LNOI2014]LCA 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3626 题意概括 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节 ...

  6. 【BZOJ3626】[LNOI2014]LCA 离线+树链剖分+线段树

    [BZOJ3626][LNOI2014]LCA Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度 ...

  7. 【BZOJ3626】LCA(树上差分,树链剖分)

    题意:给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询问给 ...

  8. [BZOJ3626] [LNOI2014]LCA(树链剖分)

    [BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...

  9. [bzoj3626][LNOI2014]LCA

    Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...

  10. 【BZOJ-3626】LCA 树链剖分

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1428  Solved: 526[Submit][Status ...

随机推荐

  1. C++中map用法

    /************************************************************************** Map的特点: 1.存储Key-value对* ...

  2. Cannot connect to (local) sql server 2008

    Make following steps to solve the issue: Cannot connect to (local). ADDITIONAL INFORMATION: Login fa ...

  3. 用Objective-C的foundation框架解决表达式求值问题

    主要思想: 本程序分2个类 一个是ExpressionString类,主要用于存储表达式以及对它进行求值.以下是该类中的内容: (NSString *)expString//用于存储要计算的表达式: ...

  4. appcan 跨窗口处理方法 appcan.window.evaluateScript({name,scriptContent,type})使用解读

    appcan.window.evaluateScript({ name,/*主窗口名称,此窗口要先用appcan.window.open打开了,才能找到,此方法才会有效*/ scriptContent ...

  5. 盗链网易163、腾讯QQ、新浪sina、百度Baidu的图片之PHP独立版

    网易相册频道,网易相册确实是一个高质量图片的地方,而且免费,唯一缺点是很多加了水印,但这个不重要了,无意间发现网易163相册频道的图片是防止盗链的,于是便自己写了一个小程序来突破这个. 本盗链图片最新 ...

  6. func_get_args的使用

    func_get_args是获取方法中参数的数组,返回的是一个数组,与func_num_args搭配使用:func_num_args一般写在方法中,用于计数:使用方法如下:function foo($ ...

  7. Linux查看目录挂载点

    用命令 df 即可 # df /var/lib/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda3 135979984 669 ...

  8. 使用ECLIPSE+MINGW搭建C/C++开发环境

    有个朋友要我帮忙跑一个C程序而我现在主要用java,电脑上也就没有C语言的编译和开发环境,在学习java的这段期间,接触到了Eclipse这个强大的IDE,用惯了.就为调试一个程序,去安装一个VS觉得 ...

  9. slqplus 帮助手册

    1.查看sqlplus的帮助是否可用,必须登录了才可用. D:\app\product\\db_1\sqlplus\admin\help>sqlplus /nolog SQL :: Copyri ...

  10. oracle expdp 无法导出SYS下特定TABLE

    创建测试表: D:\app\product\\db_1>sqlplus "/as sysdba" SQL :: Copyright (c) , , Oracle. All r ...