Description

给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。
有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LCA(i,z)]。
(即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)

Input

第一行2个整数n q。
接下来n-1行,分别表示点1到点n-1的父节点编号。
接下来q行,每行3个整数l r z。

Output

输出q行,每行表示一个询问的答案。每个答案对201314取模输出

Sample Input

5 2
0
0
1
1
1 4 3
1 4 2

Sample Output

8
5

解题思路:

蒟蒻QAQ的我一开始以为是树上莫队。

还好吧,这题其实是将Deep重新理解了一下,就是从根到这个点的距离。

我们发现可以在树链上(到1)加一,最后查询到根的权值和。

发现具有区间可减性。

线段树+树剖搞定。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef long long lnt;
const lnt mod=;
using std::sort;
struct trnt{
lnt lzt;
lnt val;
}tr[];
struct pnt{
int hd;
int fa;
int tp;
int dp;
int no;
int wgt;
int ind;
int mxs;
}p[];
struct ent{
int twd;
int lst;
}e[];
int ans[];
struct data{
int no;
bool lft;
int rgt;
int z;
}dt[];
int cnt;
int dfn;
int n,q;
bool cmp(data x,data y)
{
return x.rgt<y.rgt;
}
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void add(int l,int r,int spc,lnt x)
{
if(!spc)
return ;
tr[spc].lzt=(tr[spc].lzt+x)%mod;
tr[spc].val=(tr[spc].val+(((lnt)(r-l+))*x)%mod)%mod;
return ;
}
void pushdown(int spc,int l,int r)
{
if(tr[spc].lzt)
{
int mid=(l+r)>>;
add(l,mid,lll,tr[spc].lzt);
add(mid+,r,rrr,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void pushup(int spc)
{
tr[spc].val=(tr[lll].val+tr[rrr].val)%mod;
}
void update(int l,int r,int ll,int rr,int spc,lnt v)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
{
add(l,r,spc,v);
return ;
}
pushdown(spc,l,r);
int mid=(l+r)>>;
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
lnt query(int l,int r,int ll,int rr,int spc)
{
if(ll>r||l>rr)
return 0ll;
if(ll<=l&&r<=rr)
return tr[spc].val;
int mid=(l+r)>>;
pushdown(spc,l,r);
return (query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr))%mod;
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(p[to].wgt>maxs)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].ind=++dfn;
p[x].tp=top;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
return ;
}
void Insert(int x)
{
while(p[x].tp!=)
{
update(,n,p[p[x].tp].ind,p[x].ind,,);
x=p[p[x].tp].fa;
}
update(,n,,p[x].ind,,);
return ;
}
lnt Val(int x)
{
lnt ansl=;
while(p[x].tp!=)
{
ansl+=query(,n,p[p[x].tp].ind,p[x].ind,);
ansl%=mod;
x=p[p[x].tp].fa;
}
ansl+=query(,n,,p[x].ind,);
ansl%=mod;
return ansl;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
int a;
scanf("%d",&a);
a++;
ade(a,i);
ade(i,a);
}
cnt=;
for(int i=;i<=q;i++)
{
int tmp;
cnt++;
dt[cnt].no=i;
dt[cnt].lft=true;
scanf("%d",&dt[cnt].rgt);
cnt++;
dt[cnt].no=i;
dt[cnt].lft=false;
scanf("%d",&dt[cnt].rgt);
dt[cnt].rgt++;
scanf("%d",&tmp);
tmp++;
dt[cnt].z=dt[cnt-].z=tmp;
}
sort(dt+,dt+cnt+,cmp);
Basic_dfs(,);
Build_dfs(,);
int plc=;
for(int i=;i<=cnt;i++)
{
while(plc<=dt[i].rgt)
{
Insert(plc);
plc++;
}
int x=dt[i].no;
int pl=dt[i].z;
lnt tmp=Val(pl);
if(dt[i].lft)
tmp=-tmp;
ans[x]=(ans[x]+tmp)%mod;
}
for(int i=;i<=q;i++)
printf("%lld\n",(ans[i]%mod+mod)%mod);
return ;
}

BZOJ3626: [LNOI2014]LCA(树链剖分+线段树)的更多相关文章

  1. 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树

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

  2. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  3. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  4. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  5. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  6. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  7. BZOJ2819Nim——树链剖分+线段树+Nim游戏

    题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  8. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  9. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  10. [HDU3710] Battle Over Cities [树链剖分+线段树+并查集+kruskal+思维]

    题面 一句话题意: 给定一张 N 个点, M 条边的无向连通图, 每条边上有边权 w . 求删去任意一个点后的最小生成树的边权之和. 思路 首先肯定要$kruskal$一下 考虑$MST$里面去掉一个 ...

随机推荐

  1. iRedMail邮件系统配置简易视频安装教程

    iRedMail邮件系统配置简易视频安装教程        iRedMail邮件系统配置简易视频安装教程 iRedMail中文名为“艾瑞得邮件系统”, 属于开源的企业邮件解决方案,但其性能不逊于任何商 ...

  2. 实现人脸识别性别之路---matplotlib之注释

    一.准备数据 利用np.linspace()函数得到一定范围内的数据集 利用2*x+1的公式求出y 二.创建窗口 三.根据具有规律的数据画图 四.调整坐标轴 1.将原本的坐标轴的上轴和右轴去掉,使用基 ...

  3. Scrapy框架之日志等级

    一.日志等级 CRITICAL:严重错误 ERROR:一般错误 WARNING:警告 INFO: 一般信息 DEBUG:调试信息 [注意:默认的日志等级是DEBUG] 二.日志等级设置 修改setti ...

  4. stat---显示文件的状态信息

    stat命令用于显示文件的状态信息.stat命令的输出信息比ls命令的输出信息要更详细. 语法 stat(选项)(参数) 选项 -L:支持符号连接: -f:显示文件系统状态而非文件状态: -t:以简洁 ...

  5. 教你破解隔壁妹子wifi密码,成功率高达90%

    破解wifi密码听起来很复杂,实际上也不是非常的复杂,今天教大家如何破解隔壁妹子的wifi密码. 首先声明:本教程只用于技术交流,请勿用于非法用途.请严格遵循相关法律法规.为了保护本例中被破解密码者信 ...

  6. 36Kr众筹项目比呀比biyabi,调查分析研究报告,背后资方势力的关系梳理

    36Kr众筹项目比呀比biyabi调查报告 个层次的评价.   变革家-比呀比拆解报告:http://biangejia.com/archives/12653 8.其它 没有通过微信,参加路演,有点遗 ...

  7. UESTC 360 Another LCIS

    Another LCIS Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on UESTC. Original ...

  8. Spring MVC原理及实例基础扫盲篇

    近期 项目中刚接触了SpringMVC,就把这几天看的跟实践的东西写出来吧. 一.首先,先来了解一下SpringMVC究竟是个什么样的框架? Spring Web MVC是一种基于Java的实现了We ...

  9. Android 学习笔记之Bitmap位图的缩放

    位图的缩放也可以借助Matrix或者Canvas来实现. 通过postScale(0.5f, 0.3f)方法设置旋转角度,然后用createBitmap方法创建一个经过缩放处理的Bitmap对象,最后 ...

  10. 61.C++文件操作实现硬盘检索

    #include <iostream> #include <fstream> #include <memory> #include <cstdlib> ...