显然,暴力求解的复杂度是无法承受的。
考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r
之间的点,向上搜索到第一个有标记的点求出它的深度统计答案。观察到,深度其实就是上面有几个已标记了的点(包括自身)。所以,我们不妨把 z
到根的路径上的点全部 +1,对于 l 到 r
之间的点询问他们到根路径上的点权和。仔细观察上面的暴力不难发现,实际上这个操作具有叠加性,且可逆。也就是说我们可以对于 l 到 r 之间的点
i,将 i 到根的路径上的点全部 +1, 转而询问 z 到根的路径上的点(包括自身)的权值和就是这个询问的答案。把询问差分下,也就是用 [1,
r] − [1, l − 1] 来计算答案,那么现在我们就有一个明显的解法。从 0 到 n − 1 依次插入点 i,即将 i
到根的路径上的点全部+1。离线询问答案即可。我们现在需要一个数据结构来维护路径加和路径求和,显然树链剖分或LCT
均可以完成这个任务。树链剖分的复杂度为 O((n + q)· log n · log n),LCT的复杂度为 O((n + q)· log
n),均可以完成任务。至此,题目已经被我们完美解决。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const long long N=;
const long long mod=;
long long cnt,head[N];
long long size[N],fa[N],dep[N],son[N];
long long top[N],id[N],tot;
long long n,m,lm[N],rm[N];
struct que{
long long l,r,z;
}q[N];
struct tree{
long long l,r,sum,lazy;
}tr[N*];
vector<long long> l[N],r[N];
struct edge{
long long to,nxt;
}e[N*];
void add(long long u,long long v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void dfs1(long long u,long long f,long long deep){
size[u]=;
fa[u]=f;
dep[u]=deep;
long long maxson=-;
for(long long i=head[u];i;i=e[i].nxt){
long long v=e[i].to;
if(v==f)continue;
dfs1(v,u,deep+);
size[u]+=size[v];
if(size[v]>maxson){
maxson=size[v];
son[u]=v;
}
}
}
void dfs2(long long u,long long tp){
top[u]=tp;
id[u]=++tot;
if(!son[u])return;
dfs2(son[u],tp);
for(long long i=head[u];i;i=e[i].nxt){
long long v=e[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void build(long long l,long long r,long long now){
tr[now].l=l;tr[now].r=r;
if(l==r)return;
long long mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
}
void update(long long now){
tr[now].sum=tr[now*].sum+tr[now*+].sum;
tr[now].sum%=mod;
}
void pushdown(long long now){
if(tr[now].lazy==)return;
tr[now*].sum+=((tr[now*].r-tr[now*].l+)*tr[now].lazy)%mod;
tr[now*].sum%=mod;
tr[now*+].sum+=((tr[now*+].r-tr[now*+].l+)*tr[now].lazy)%mod;
tr[now*+].sum%=mod;
tr[now*].lazy+=tr[now].lazy;
tr[now*].lazy%=mod;
tr[now*+].lazy+=tr[now].lazy;
tr[now*+].lazy%=mod;
tr[now].lazy=;
}
void change(long long l,long long r,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].sum+=(tr[now].r-tr[now].l+)%mod;
tr[now].sum%=mod;
tr[now].lazy+=;
return;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)change(l,r,now*+);
else if(r<=mid)change(l,r,now*);
else{
change(l,mid,now*);
change(mid+,r,now*+);
}
update(now);
}
long long getsum(long long l,long long r,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
return tr[now].sum;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return getsum(l,r,now*+);
else if(r<=mid)return getsum(l,r,now*);
else {
return (getsum(l,mid,now*)+getsum(mid+,r,now*+))%mod;
}
}
void changel(long long x,long long y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(id[top[x]],id[x],);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
change(id[x],id[y],);
}
long long getsuml(long long x,long long y){
long long ans=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=getsum(id[top[x]],id[x],);
ans%=mod;
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=getsum(id[x],id[y],);
ans%=mod;
return ans;
}
int main(){
scanf("%lld%lld",&n,&m);
for(long long i=;i<=n;i++){
long long u;
scanf("%lld",&u);
add(u+,i);add(i,u+);
}
dfs1(,,);
dfs2(,);
build(,n,);
for(long long i=;i<=m;i++){
scanf("%lld%lld%lld",&q[i].l,&q[i].r,&q[i].z);
q[i].l++;q[i].r++;q[i].z++;
l[q[i].l-].push_back(i);
r[q[i].r].push_back(i);
}
for(long long i=;i<=n;i++){
changel(i,);
for(long long j=;j<l[i].size();j++){
lm[l[i][j]]=getsuml(q[l[i][j]].z,);
}
for(long long j=;j<r[i].size();j++){
rm[r[i][j]]=getsuml(q[r[i][j]].z,);
}
}
for(long long i=;i<=m;i++){
printf("%lld\n",(rm[i]-lm[i]+mod)%mod);
}
return ;
}

BZOJ 3626 LCA(离线+树链剖分+差分)的更多相关文章

  1. BZOJ 3626 LCA(离线+树链剖分)

    首先注意到这样一个事实. 树上两个点(u,v)的LCA的深度,可以转化为先将u到根路径点权都加1,然后求v到根路径上的总点权值. 并且该题支持离线.那么我们可以把一个区间询问拆成两个前缀和形式的询问. ...

  2. bzoj 3626: [LNOI2014]LCA 离线+树链剖分

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

  3. [BZOJ3626] [LNOI2014] LCA 离线 树链剖分

    题面 考虑到询问的\(l..r,z\)具有可减性,考虑把询问差分掉,拆成\(r,z\)和\(l-1,z\). 显然这些LCA一定在\(z\)到根的路径上.下面的问题就是怎么统计. 考虑不是那么暴力的暴 ...

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

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

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

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

  6. BZOJ 3626 离线+树链剖分+线段树

    思路: 抄一波yousiki的- 显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案 ...

  7. 【树链剖分 差分】bzoj3626: [LNOI2014]LCA

    把LCA深度转化的那一步还是挺妙的.之后就是差分加大力数据结构了. Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep ...

  8. JZYZOJ1454 NOIP2015 D2T3_运输计划 二分 差分数组 lca tarjan 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1454 从这道题我充分认识到我的脑子里好多水orz. 如果知道了这个要用二分和差分写,就没什么思考上的难点了(屁咧你写了一 ...

  9. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

随机推荐

  1. Idea配置文件的读取

    开发过程中遇到配置文件读取问题,因此记录以后运用的到. 配置文件位置: 配置文件内容: default_size = 100 grid_size = 20 delayTime = 200 配置文件读取 ...

  2. 12.boost有向图无向图(矩阵法)

    #include <iostream> #include <boost/config.hpp> //图 #include <boost/graph/adjacency_m ...

  3. Windows服务的创建,安装,卸载

    我公司项目的产线系统要与WMS物流系统做借口对接,需要我创建一个windows服务的项目,里面含有7个服务 创建Windows服务: 1.如图:点击 windows->经典桌面->wind ...

  4. Pyinstaller 0

    Pyinstaller 是一个小的可以打包我们所写的Python脚本,来生成相应的可执行文件. 它是怎么工作的? PyInstaller读取您编写的Python脚本.它会分析您的代码,以发现您的脚本执 ...

  5. activity(工作流)初步学习记录

    1.概念 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现某个预期 ...

  6. 关于目标检测 Object detection

    NO1.目标检测 (分类+定位) 目标检测(Object Detection)是图像分类的延伸,除了分类任务,还要给定多个检测目标的坐标位置.      NO2.目标检测的发展 R-CNN是最早基于C ...

  7. 预测一下web前端未来的6个趋势

    2018年前端技术的发展也将进入到一个相对稳定的阶段, 就前端主流技术框架的发展而言,过去的几年里发展极快,在填补原有技术框架空白和不足的同时也渐渐趋于成熟. 未来前端在已经趋向成熟的技术方向上面将会 ...

  8. React中的AES加解密请求

    引言 在我们使用React开发Web前端的时候,如果是比较大的项目和正常的项目的话,我们必然会用到加解密,之前的文章中提到.NET的一些加解密,那么,这里我就模拟一个例子: 1.后台开发API接口,但 ...

  9. [洛谷P1352][codevs1380]没有上司的舞会

    题目大意:某大学有N个职员,编号为1~N.他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但如果某个职员的上司来参加舞 ...

  10. PHP JWT初识

    一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt.才发现jwt已经被大家广泛的应用了.看来我有点out了.哈哈,趁着这个世界来好好看看这个. JWT(JSON Web Token ...