[LNOI 2014]LCA
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
0
0
1
1
1 4 3
1 4 2
Sample Output
5
HINT
共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。
题解
[HNOI 2015]开店的简化版。
- //It is made by Awson on 2018.1.8
- #include <set>
- #include <map>
- #include <cmath>
- #include <ctime>
- #include <queue>
- #include <stack>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <cstdlib>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #define LL long long
- #define RE register
- #define lowbit(x) ((x)&(-(x)))
- #define Max(a, b) ((a) > (b) ? (a) : (b))
- #define Min(a, b) ((a) < (b) ? (a) : (b))
- #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
- using namespace std;
- const int N = ;
- const int MOD = ;
- const int INF = ~0u>>;
- int n, q, f, u, v, c, fa[N+], dep[N+], top[N+], cnt, size[N+], son[N+], pos[N+];
- struct tt {
- int to, next;
- }edge[N+];
- int path[N+], tot;
- void add(int u, int v) {
- edge[++tot].to = v;
- edge[tot].next = path[u];
- path[u] = tot;
- }
- struct Segment_tree {
- int root[N+], sum[N*+], lazy[N*+], ch[N*][], pos;
- int newnode(int r) {
- int o = ++pos; sum[o] = sum[r], lazy[o] = lazy[r], ch[o][] = ch[r][], ch[o][] = ch[r][];
- return o;
- }
- void update(int &o, int l, int r, int a, int b, int last) {
- if (o <= last) o = newnode(o);
- if (a <= l && r <= b) {
- sum[o] += r-l+, sum[o] %= MOD, lazy[o]++; return;
- }
- int mid = (l+r)>>;
- if (mid >= a) update(ch[o][], l, mid, a, b, last);
- if (mid < b) update(ch[o][], mid+, r, a, b, last);
- sum[o] = (sum[ch[o][]]+sum[ch[o][]]+(LL)lazy[o]*(r-l+)%MOD)%MOD;
- }
- int query(int o, int l, int r, int a, int b) {
- if (!o) return ;
- if (a <= l && r <= b) return sum[o];
- int mid = (l+r)>>, c1 = , c2 = ;
- if (mid >= a) c1 = query(ch[o][], l, mid, a, b);
- if (mid < b) c2 = query(ch[o][], mid+, r, a, b);
- return (c1+c2+(LL)lazy[o]*(Min(r, b)-Max(l, a)+)%MOD)%MOD;
- }
- }T;
- void dfs1(int o, int father, int depth) {
- fa[o] = father, dep[o] = depth+, size[o] = ;
- for (int i = path[o]; i; i = edge[i].next) {
- dfs1(edge[i].to, o, depth+);
- size[o] += size[edge[i].to];
- if (size[edge[i].to] > size[son[o]]) son[o] = edge[i].to;
- }
- }
- void dfs2(int o, int tp) {
- top[o] = tp, pos[o] = ++cnt;
- if (son[o]) dfs2(son[o], tp);
- for (int i = path[o]; i; i = edge[i].next)
- if (edge[i].to != son[o]) dfs2(edge[i].to, edge[i].to);
- }
- void lca_update(int id, int o, int last) {while (top[o]) T.update(T.root[id], , n, pos[top[o]], pos[o], last), o = fa[top[o]]; }
- int lca_query(int id, int o) {
- int ans = ;
- while (top[o]) ans += T.query(T.root[id], , n, pos[top[o]], pos[o]), ans %= MOD, o = fa[top[o]];
- return ans;
- }
- void work() {
- scanf("%d%d", &n, &q);
- for (int i = ; i <= n; i++) scanf("%d", &f), add(f+, i);
- dfs1(, , ), dfs2(, );
- for (int i = ; i <= n; i++) {
- T.root[i] = T.root[i-]; lca_update(i, i, T.pos);
- }
- while (q--) {
- scanf("%d%d%d", &u, &v, &c);
- printf("%d\n", (lca_query(v+, c+)-lca_query(u, c+)+MOD)%MOD);
- }
- }
- int main() {
- work();
- return ;
- }
[LNOI 2014]LCA的更多相关文章
- 解题:LNOI 2014 LCA
题面 这题有点意思 转化问题,我们把询问区间的点到根链加,再查询询问点到根的权值和就是每个询问的答案. 然后如果你数据结构没学傻只需要差分一下就可以扫一遍出解了 #include<cstdio& ...
- 【LNOI 2014】 LCA
[题目链接] 点击打开链接 [算法] 考虑求lca(x,y)的深度 我们可以将从根到x路径上的点都打上标记,然后,询问y到根上路径的权值和 那么,求sigma(depth(lca(i,z)))(l & ...
- bzoj 4012: [HNOI2015]开店
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- [GXOI/GZOI2019]旧词
很像LNOI 2014 LCA那道题. 同样的套路,离线以后直接扫描线. k=1的话就是原题. 考虑一般情况. 原本的做法是对x到根的这条链做一下区间+1操作,目的是为了是的在深度为i的位置得到的贡献 ...
- bzoj 4012: [HNOI2015]开店 主席树
Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...
- BZOJ 5507: [gzoi2019]旧词 LCT
和之前那个 [LNOI]LCA 几乎是同一道题,就是用动态树来维护查分就行. code: #include <bits/stdc++.h> using namespace std; #de ...
- [HNOI2015]开店 简要题解
主席树. 推下式子,发现点的深度和好算,lca深度和不好算. lca深度之和有个套路:先给a到根路径+1,再算b到根的和. 如果可以离线,即LNOI的LCA.本题强制在线,可持久化. 由于区间修改,使 ...
- HDU_4912 Path on the tree 2014多校5 贪心+LCA
当时刚学LCA-tarjan不久,就比赛有这个题,但没想到还是没做出来..一开始以为是DP来着,没想到是贪心,想想也对,从树的最下层开始,每次遇到询问的点,就找到他们的LCA(路径里面必经LCA),然 ...
- LOJ #2876. 「JOISC 2014 Day2」水壶 BFS+最小生成树+倍增LCA
非常好的一道图论问题. 显然,我们要求城市间的最小生成树,然后查询路径最大值. 然后我们有一个非常神的处理方法:进行多源 BFS,处理出每一个城市的管辖范围. 显然,如果两个城市的管辖范围没有交集的话 ...
随机推荐
- [福大软工教学] W班 第1次成绩排行榜
作业地址 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/837 作业要求 (1)回想一下你初入大学时对 ...
- beta冲刺5
昨天的问题: 登陆页面的整合重新制作 各主机版本更迭 我的社团显示功能修改调整 主页的头部替换掉 +修复帖子无法显示内容的问题 +试着将邮箱等判定用正则表达式进行实时判定. 今天的完成: 主要是线下进 ...
- Beta 第七天
今天遇到的困难: 构造新适配器的时候出现了某些崩溃的问题 ListView监听器有部分的Bug 今天完成的任务: 陈甘霖:完成相机调用和图库功能,完成阿尔法项目遗留下来的位置调用问题,实现百度定位 蔡 ...
- Alpha第四天
Alpha第四天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...
- C语言嵌套循环
题目一:7-3 编程打印空心字符菱形 1.提交列表 2.设计思路: 1.定义整型变量循环控制变量i,j,k,x,y,z,e及菱形的高度height: 2.定义字符型变量letter: 3.输入字符型变 ...
- bug终结者 团队作业第二周
bug终结者 团队作业第二周 我们小组选取游戏"开心消消乐",回答问题: 1. 此类软件是什么时候开始出现的, 这些软件是怎么说服你(陌生人)成为他们的用户的? 他们的目标都是盈利 ...
- 201621123057 《Java程序设计》第7周学习总结
1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 答: ...
- [Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法
博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...
- day-5 python协程与I/O编程深入浅出
基于python编程语言环境,重新学习了一遍操作系统IO编程基本知识,同时也学习了什么是协程,通过实际编程,了解进程+协程的优势. 一.python协程编程实现 1. 什么是协程(以下内容来自维基百 ...
- 读取.properties的内容1
属性文件方便于项目进行更改,在项目开发中用的也是非常的普遍,在这里就把属性文件的读取通过代码进行一个小结: package com.oyy.test; import java.io.BufferedI ...