题意

存在一棵树,每次询问 \(l, r, z\)

\[\sum_{i = l} ^ {r} deep(lca(i, z))
\]


考虑 lca 的实质:两点到根的路径的交集中深度最大的点

其中一点到根的路径上经过的存在于另一点到根的路径上的点一定存在于 lca 到根的路径上

这样的话,对 \([l, r]\) 内的每个点,在其到根的路径上的权 + 1;

查询答案时,就是询问 \(z\) 到根节点的价值和

统计答案是有个小技巧

首先将所有的询问的 \(l, r\) 存到数组中,从小到大扫

如果是某个询问的左端点,查询并记录

如果是右端点,查询,减去相应的左端点就是该询问的答案


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string> using namespace std; const int N = 5e4 + 10;
const int Mod = 201314; #define LL long long #define int long long int topp[N], fa[N], size[N], son[N], deep[N], tree[N];
int Tree;
LL W[N << 2], F[N << 2], S[N << 2];
struct Node {int u, v, nxt;} G[N << 1];
int now, head[N];
int n, q;
struct Node_ {
int l, r, z, id;
} Ask[N]; struct Node_2 {
int l, opt, id;
} Ask2[N << 1]; #define gc getchar() inline int read() {
int x = 0; char c = gc;
while(c < '0' || c > '9') c = gc;
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
return x;
} void Link(int u, int v) {G[++ now].v = v; G[now].nxt = head[u]; head[u] = now;} void Dfs_1(int u, int f_, int dep) {
fa[u] = f_, deep[u] = dep, size[u] = 1;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v == f_) continue;
Dfs_1(v, u, dep + 1);
size[u] += size[v];
if(size[son[u]] < size[v]) son[u] = v;
}
} void Dfs_2(int u, int tp) {
topp[u] = tp, tree[u] = ++ Tree;
if(!son[u]) return ;
Dfs_2(son[u], tp);
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v != fa[u] && v != son[u]) Dfs_2(v, v);
}
} #define lson jd << 1
#define rson jd << 1 | 1 void Build_tree(int l, int r, int jd) {
S[jd] = r - l + 1;
if(l == r) return ;
int mid = (l + r) >> 1;
Build_tree(l, mid, lson), Build_tree(mid + 1, r, rson);
} void Push_down(int jd) {
(F[lson] += F[jd]) %= Mod, (F[rson] += F[jd]) %= Mod;;
(W[lson] += S[lson] * F[jd]) %= Mod, (W[rson] += S[rson] * F[jd]) %= Mod;
F[jd] = 0;
} void Sec_G(int l, int r, int jd, int x, int y, int opt) {
if(x <= l && r <= y) {
(F[jd] += opt) %= Mod;
(W[jd] += S[jd] * opt) %= Mod;
return ;
}
if(F[jd]) Push_down(jd);
int mid = (l + r) >> 1;
if(x <= mid) Sec_G(l, mid, lson, x, y, opt);
if(y > mid) Sec_G(mid + 1, r, rson, x, y, opt);
W[jd] = W[lson] + W[rson];
} void Sec_G_imp(int x, int opt) {
int tpx = topp[x];
while(tpx != 1) {
Sec_G(1, n, 1, tree[tpx], tree[x], opt);
x = fa[tpx], tpx = topp[x];
}
Sec_G(1, n, 1, tree[1], tree[x], opt);
} int ret; void Sec_A(int l, int r, int jd, int x, int y) {
if(x <= l && r <= y) {
(ret += W[jd]) %= Mod;
return ;
}
if(F[jd]) Push_down(jd);
int mid = (l + r) >> 1;
if(x <= mid) Sec_A(l, mid, lson, x, y);
if(y > mid) Sec_A(mid + 1, r, rson, x, y);
} inline int Sec_A_imp(int x) {
int tpx = topp[x];
ret = 0;
while(tpx != 1) {
Sec_A(1, n, 1, tree[tpx], tree[x]);
x = fa[tpx], tpx = topp[x];
}
Sec_A(1, n, 1, tree[1], tree[x]);
return ret % Mod;
} int Answer[N];
int PreSum[N]; inline bool Cmp(Node_2 a, Node_2 b) {
return a.l < b.l;
} main() {
n = read(), q = read();
for(int i = 1; i <= n; i ++) head[i] = -1;
for(int i = 1; i < n; i ++) {
int u = read() + 1;
Link(u, i + 1), Link(i + 1, u);
}
Dfs_1(1, 0, 1);
Dfs_2(1, 1);
Build_tree(1, n, 1);
for(int i = 1; i <= q; i ++)
Ask[i].l = read() + 1, Ask[i].r = read() + 1, Ask[i].z = read() + 1, Ask[i].id = i;
int js = 0;
for(int i = 1; i <= q; i ++) {
Ask2[++ js].l = Ask[i].l - 1; Ask2[js].id = i; Ask2[js].opt = 1;
Ask2[++ js].l = Ask[i].r; Ask2[js].id = i; Ask2[js].opt = 0;
}
sort(Ask2 + 1, Ask2 + js + 1, Cmp);
int L = 0;
for(int i = 1; i <= js; i ++) {
while(L < Ask2[i].l) {
L ++;
Sec_G_imp(L, 1);
}
if(Ask2[i].opt == 1) {
PreSum[Ask2[i].id] = Sec_A_imp(Ask[Ask2[i].id].z);
} else {
Answer[Ask2[i].id] = Sec_A_imp(Ask[Ask2[i].id].z);
Answer[Ask2[i].id] -= PreSum[Ask2[i].id];
(Answer[Ask2[i].id] += Mod) %= Mod;
}
}
for(int i = 1; i <= q; i ++) cout << Answer[i] << "\n";
return 0;
}

luogu 4211的更多相关文章

  1. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  2. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  3. [luogu P2170] 选学霸(并查集+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...

  4. [luogu P2647] 最大收益(贪心+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...

  5. Luogu 考前模拟Round. 1

    A.情书 题目:http://www.luogu.org/problem/show?pid=2264 赛中:sb题,直接暴力匹配就行了,注意一下读入和最后一句话的分句 赛后:卧槽 怎么只有40 B.小 ...

  6. luogu P2580 于是他错误的点名开始了

    luogu  P2580 于是他错误的点名开始了 https://www.luogu.org/problem/show?pid=2580 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边 ...

  7. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  8. Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂)

    Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂) Description 广义的斐波那契数列是指形如\[A_n=p*a_{n-1}+q*a_{n-2}\]的数列.今给定数列的两系数p和q, ...

  9. Luogu 1962 斐波那契数列(矩阵,递推)

    Luogu 1962 斐波那契数列(矩阵,递推) Description 大家都知道,斐波那契数列是满足如下性质的一个数列: f(1) = 1 f(2) = 1 f(n) = f(n-1) + f(n ...

随机推荐

  1. nmap使用帮助翻译

    Nmap 7.60 ( https://nmap.org )Usage: nmap [扫描类型] [操作] {目标说明}目标说明:  可以识别主机名.IP地址.网络,等等.  例如: scanme.n ...

  2. Mybatis之关联关系(一对多、多对多)

    目的: Mybatis关系映射之一对多 Mybatis关系映射之多对多 Mybatis关系映射之一对多 一对多 (订单对应多个订单项) 多对一  (订单项对应一个订单) 其是映射关系的基层思维是一样的 ...

  3. 血小板 live2d web使用

    关于此插件 看到一个很多网站都有动态的小人,目前除了即将废弃的flash就是canvas和h5动画了,h5动画能力有限,不能画出复杂的效果 那么canvas就是首选,全部手画也不可能,大部分使用库和工 ...

  4. Java 处理异常 9 个最佳实践,你知道几个?

    1. 在Finally中清理资源或者使用Try-With-Resource语句 使用Finally Java 7的Try-With-Resource语句 2. 给出准确的异常处理信息 3. 记录你所指 ...

  5. 前端开发 Vue -4promise解读1

    JS(JavaScript) - Promise 2015年6月, ES2015(即 ECMAScript 6.ES6) 正式发布.其中 Promise 被列为正式规范,成为 ES6 中最重要的特性之 ...

  6. input 被checked时和label配合的妙用

    input 和label配合的妙用 1:作为文字隐藏与否的开关: 如下代码:对div里面所包含的文字较多,一开始只展示小部分,当用户点击按钮时,进行全部内容的展示(按钮是以向下隐藏箭头的图片) htm ...

  7. Microsoft Word (2016) Deceptive File Reference ZDI-CAN-7949

    [+] Credits: John Page (aka hyp3rlinx) [+] Website: hyp3rlinx.altervista.org[+] Source:  http://hyp3 ...

  8. 关于lock和synchronized的选择

    这里不介绍具体用法,介绍lock和synchronized的不同从而做出选择 1.lock是一个接口,而synchronized是java中的一个关键字,synchronized是内置的语言实现. 2 ...

  9. git推送代码Gogs报401错误

    1.git push 报错:RPC failed; HTTP 401 curl 22 The requested URL returned error: 401 The remote end hung ...

  10. java 扫描微信公众号二维码,关注并登录逻辑

    场景:户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录. 逻辑: 系统生成带参数的临时二维码:参数 scene_str 自定义为唯一值(可以是uuid),临时二维码的生成方式参照官方接 ...