题目链接

思路

我们换一种求\(dep[lca(i,j)]\)的方法。

将从根到\(i\)的路径上所有点的权值加\(1\),然后求从根节点到j路径上点的权值和。就是\(i\)和\(j\)的\(lca\)的深度。

以此类推,对于求\(\sum\limits_{i=l}^rdep[lca(i,z)]\),我们可以对于从l到r中的每个节点到根节点的路径上的点权值加\(1\),然后求一边从\(z\)到根节点路径和即可。这个可以用树链剖分做到。

然后再考虑多次询问。发现这个题可以离线。那就比较好处理了。

因为每次询问都是形如\([l,r]\)的形式。所以可以通过\([0,r]-[0,l-1]\)来得到\([l,r]\)的答案。所以我们对于询问离线之后,分别在每次询问的\(l-1\)和\(r\)处询问一次。相减就是答案。

代码

/*
* @Author: wxyww
* @Date: 2019-01-29 14:50:20
* @Last Modified time: 2019-01-29 16:13:25
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
#define int ll
const int N = 100010,mod = 201314;
vector<int>e[N];
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
} int dep[N],top[N],son[N],dfn[N],siz[N],fa[N];
void dfs1(int u,int father) {
fa[u] = father;dep[u] = dep[father] + 1;siz[u] = 1;
int k = e[u].size();
for(int i = 0;i < k;++i) {
int v = e[u][i];
if(v == father) continue;
dfs1(v,u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
} int tot;
void dfs2(int u,int father,int tt) {
dfn[u] = ++tot;top[u] = tt;
int k = e[u].size();
if(!son[u]) return;
dfs2(son[u],u,tt);
for(int i = 0;i < k;++i) {
int v = e[u][i];
if(v == father || v == son[u]) continue;
dfs2(v,u,v);
}
} int tree[N << 2],lazy[N << 2];
void pushup(int rt) {
tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]) % mod;
} void pushdown(int rt,int ln,int rn) {
if(lazy[rt]) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1] %= mod;
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt << 1 | 1] %= mod;
tree[rt << 1] += lazy[rt] * ln;
tree[rt << 1] %= mod;
tree[rt << 1 | 1] += lazy[rt] * rn;
tree[rt << 1 | 1] %= mod;
lazy[rt] = 0;
}
} void update(int rt,int l,int r,int L,int R,int c) {
if(L <= l && R >= r) {
lazy[rt] += c;
lazy[rt] %= mod;
tree[rt] += c * (r - l + 1);
tree[rt] %= mod;
return;
}
int mid = (l + r) >> 1;
pushdown(rt,mid - l + 1,r - mid);
if(L <= mid) update(rt << 1,l,mid,L,R,c);
if(R > mid) update(rt << 1 | 1,mid + 1,r,L,R,c);
pushup(rt);
} int query(int rt,int l,int r,int L,int R) {
if(L <= l && R >= r)
return tree[rt];
int mid = (l + r) >> 1;
pushdown(rt,mid - l + 1,r - mid);
int ans = 0;
if(L <= mid) ans += query(rt << 1,l,mid,L,R),ans %= mod;
if(R > mid) ans += query(rt << 1 | 1,mid + 1,r,L,R),ans %= mod;
return ans;
} void UPDATE(int rt,int c) {
while(rt != 0) {
update(1,1,tot,dfn[top[rt]],dfn[rt],c);
rt = fa[top[rt]];
}
} int Query(int rt) {
int ans = 0;
while(rt != 0) {
ans += query(1,1,tot,dfn[top[rt]],dfn[rt]);
ans %= mod;
rt = fa[top[rt]];
}
return ans;
} struct node {
int id,z,x,ans;
}ask[N]; bool cmp(node x,node y) {
return x.x < y.x;
} bool cmp2(node x,node y) {
return x.id < y.id;
}
int js;
signed main() {
int n = read(),Q = read();
for(int i = 2;i <= n;++i) {
int x = read() + 1;
e[i].push_back(x);e[x].push_back(i);
}
for(int i = 1;i <= Q;++i) {
int l = read() + 1,r = read() + 1,z = read() + 1;
ask[++js].id = js;
ask[js].x = l - 1;ask[js].z = z;
ask[++js].id = js;
ask[js].x = r;ask[js].z = z;
}
dfs1(1,0);
dfs2(1,0,1);
sort(ask + 1,ask + js + 1,cmp);
int now = 1;
while(ask[now].x == 0) ++now;
for(int i = 1;i <= n;++i) {
UPDATE(i,1);
while(ask[now].x == i) {
ask[now].ans = Query(ask[now].z);
++now;
}
}
sort(ask + 1,ask + js + 1,cmp2);
for(int i = 2;i <= js;i += 2)
printf("%lld\n",(ask[i].ans - ask[i - 1].ans + mod) % mod);
return 0;
}

luogu4211 LCA的更多相关文章

  1. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  2. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

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

  3. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  4. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  5. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  6. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  7. [bzoj3626][LNOI2014]LCA

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

  8. (RMQ版)LCA注意要点

    inline int lca(int x,int y){ if(x>y) swap(x,y); ]][x]]<h[rmq[log[y-x+]][y-near[y-x+]+]])? rmq[ ...

  9. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

随机推荐

  1. CBV源码分析+APIVIew源码分析

    {drf,resful,apiview,序列化组件,视图组件,认证组件,权限组件,频率组件,解析器,分页器,响应器,URL控制器,版本控制} 一.CBV源码分析准备工作: 新建一个Django项目 写 ...

  2. Airflow 使用随笔(内含 TimeZone 和 Backfill 等的详解)

    其实怎么部署  airflow 又哪些特性,然后功能又是如何全面都可以在 Reference 的文章里面找到,都不是重点这里就不赘述了. 这里重点谈一下我在部署完成仔细阅读文档之后觉得可以总结的一些东 ...

  3. ssl证书部署问题

    问:我现在得到的ssl证书是.crt和.key两个在nginx环境下部署的证书,如果我们改用是tomcat,现在把这两个文件合成了.jks给tomcat使用,合成的时候输入的jks密码是不是就是部署在 ...

  4. SSH本地端口转发的理解

    ssh -L 3307:127.0.0.1:3306 user@ssh-server -N 其中127.0.0.1:3306是指 ssh-server要访问资源的ip和端口 而3307则是隧道的开口, ...

  5. 使用javaWeb的二大(Listener、Filter)组件实现分IP统计访问次数

    分析: 统计工作需要在所有资源之前都执行,那么就可以放到Filter中. 我们这个过滤器不打算做拦截操作!因为我们只是用来做统计 用什么东西来装载统计的数据.Map<String,Integer ...

  6. Lodop生成文档式模版

    Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍文档式模版的生成方法.两种模版都可以存入一下地方进行调用,比 ...

  7. Lodop获取全部JS代码,传统JS模版的生成

    Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍传统JS模版的生成方法.两种模版都可以存入一下地方进行调用, ...

  8. Tembin

    1:组织机构和用户之间是多对一的关系,一个组织结构可以有多个成员,一个成员只能属于一个组织机构. 2:app里面的邀请成员:是邀请发送短信通知用户注册tembin账户,当用户去注册的时候下面就会显示所 ...

  9. SQL to JSON Data Modeling with Hackolade

    Review: SQL to JSON data modeling First, let’s review, the main way to represent relations in a rela ...

  10. bzoj1861

    bzoj1861[ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本 ...