正解:树剖+线段树

解题报告:

传送门$QwQ$

看到$dep[lca]$啥的就想到之前托腮腮$CSP$模拟$D1T3$的那个套路,,,

然后试下这个想法,于是$dep[lca(x,y)]=\sum_{i=1}^{\infty}[i\leq dep[lca(x,y)]]$,就可以是,从$x$到根全部加一然后查询$y$到根的权值和.

现在变成$\sum_{i=l}^r dep[lca(i,x)]$,那就$l$到$r$到根全加一然后查询$x$到根的权值和.

显然考虑差分呗?就$1$到$r$全加一的权值和减去$1$到$l-1$全加一的权值和.

于是就从$1$枚举到$n$每次从当前节点到根全加一,顺便维护下这个答案就完事$QwQ$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define lowbit(x) (x&(-x))
#define rg register
#define gc getchar()
#define ls(x) (x<<1)
#define rs(x) ((x<<1)|1)
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];~i;i=edge[i].nxt) const int N=+,mod=;
int n,q,dfn[N],sz[N],top[N],fa[N],as[N],hs[N],dfn_cnt,tr[N<<],ad[N<<];
vector<int>son[N];
struct node{int id,x,op;};
vector<node>V[N]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void add(ri &x,ri y){x+=y;if(x>=mod)x-=mod;if(x<)x+=mod;}
il void dfs1(ri x)
{
sz[x]=;ri siz=son[x].size();
rp(i,,siz-){dfs1(son[x][i]),sz[x]+=sz[son[x][i]];if(sz[son[x][i]]>sz[hs[x]])hs[x]=son[x][i];}
}
il void dfs2(ri x,ri tp)
{
top[x]=tp;dfn[x]=++dfn_cnt;if(hs[x])dfs2(hs[x],tp);ri siz=son[x].size();
rp(i,,siz-)if(son[x][i]^hs[x])dfs2(son[x][i],son[x][i]);
}
il void pushdown(ri x,ri l,ri r)
{
if(!ad[x])return;
ri mid=(l+r)>>;
add(tr[ls(x)],1ll*ad[x]*(mid-l+)%mod),add(tr[rs(x)],1ll*ad[x]*(r-mid)%mod);
ad[ls(x)]+=ad[x],ad[rs(x)]+=ad[x];ad[x]=;
}
void modify(ri x,ri l,ri r,ri to_l,ri to_r)
{
if(to_l<=l && r<=to_r){add(tr[x],r-l+);add(ad[x],);return;}
pushdown(x,l,r);
ri mid=(l+r)>>;if(mid>=to_l)modify(ls(x),l,mid,to_l,to_r);if(mid<to_r)modify(rs(x),mid+,r,to_l,to_r);
tr[x]=(tr[ls(x)]+tr[rs(x)])%mod;
}
int query(ri x,ri l,ri r,ri to_l,ri to_r)
{
if(to_l<=l && r<=to_r)return tr[x];
pushdown(x,l,r);ri mid=(l+r)>>,ret=;
if(mid>=to_l)ret=query(ls(x),l,mid,to_l,to_r);;if(mid<to_r)add(ret,query(rs(x),mid+,r,to_l,to_r));
return ret;
} int main()
{
freopen("4211.in","r",stdin);freopen("4211.out","w",stdout);
n=read();q=read();rp(i,,n)son[fa[i]=read()+].push_back(i);dfs1();dfs2(,);
rp(i,,q){ri l=read(),r=read()+,x=read()+;V[l].push_back((node){i,x,-});V[r].push_back((node){i,x,});}
rp(i,,n)
{
ri nw=i;while(nw)modify(,,n,dfn[top[nw]],dfn[nw]),nw=fa[top[nw]];
for(auto j:V[i])
{nw=j.x;while(nw)add(as[j.id],j.op*query(,,n,dfn[top[nw]],dfn[nw])),nw=fa[top[nw]];}
}
rp(i,,q)printf("%d\n",as[i]);
return ;
}

洛谷$P4211\ [LNOI2014]\ LCA$ 树链剖分+线段树的更多相关文章

  1. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

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

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

  3. 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点

    题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...

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

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

  5. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  6. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  7. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  8. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  9. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  10. 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 ...

随机推荐

  1. 14.libgdx的一些坑记录(持续更新)

    1. internal的文件路径 无法用list获取目录下文件     2.动态打包散图无法放入资源管理器,只能在资源加载器打包后的散图再合成打包,但都不如提前打包 3.资源加载器读入以texture ...

  2. hihocoder1994 树与落叶 DFS+前缀和+二分

    DFS找到节点删除的时间,删除的时间其实就是子树的最长链,然后给每个点打一个时间戳,然后求每个时间点对应删除的节点的个数,对于1-max_time时间戳求一个前缀和,然后二分找到和m距离最近的那一天 ...

  3. jQuery对html元素的取值与赋值实例详解

    jQuery对html元素的取值与赋值实例详解 转载  2015-12-18   作者:欢欢   我要评论 这篇文章主要介绍了jQuery对html元素的取值与赋值,较为详细的分析了jQuery针对常 ...

  4. Getting started with the basics of programming exercises_4

    1.编写一个删除C语言程序中所有的注释语句的程序.要正确处理带引号的字符串与字符串常量,C语言中程序注释不允许嵌套. #include<stdio.h> void rcomment(int ...

  5. IP地址、域名、DNS、URL图解

  6. 20190527-JavaScriptの打怪升级旅行 { 语句 [ 声明 ,变量 ] }

    写在前面的乱七八糟:时间总是轻易地溜走,不留一丝念想,近一个月,倒是过得有点丧,从今天开始起,已经开始接触后台了,而JavaScript也只是大致有了个分类框架,那些细枝末节还有的补,任重道远,天将降 ...

  7. H3C Comware的作用

  8. tensorflow入门——5tensorflow安装

    你将把你学到的神经网络的知识,借助 TensorFlow ,一个 Google 开源的深度学习框架,应用在真实的数据集中. 你将使用 TensorFlow 来辨别 notMNIST 数据集.它是一个由 ...

  9. PHP中 spl_autoload_register() 函数用法

    这篇文章主要介绍了PHP中spl_autoload_register()函数用法,结合实例形式分析了__autoload函数及spl_autoload_register函数的相关使用技巧,需要的朋友可 ...

  10. SuperSocket通过 SessionID 获取 Session

    前面提到过,如果你获取了连接的 Session 实例,你就可以通过 "Send()" 方法向客户端发送数据.但是在某些情况下,你无法直接获取 Session 实例. SuperSo ...