3626: [LNOI2014]LCA

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2885  Solved: 1133
[Submit][Status][Discuss]

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

5 2
0
0
1
1
1 4 3
1 4 2

Sample Output

8
5

考虑暴力

假设每次查询只有一个点x而不是一段区间,那么只要将x点到根这段路径上所有的点权值+1就好了

这样对于树上所有的点z,z与x的最近公共祖先深度就是z到根这段路程的权值和

既然查询的是区间,那么对于区间中所有的节点,它们到根的这段路程都额外+1,然后再查询就好了

每次修改和查询树链剖分的话都可以直接线段树维护,复杂度(log²n)

考虑离线,编号从1到n,依次添加它们到根的这段路径的权值,当添加完第x个点之后,

z到根的路径权值之和就是答案∑LCA(i, z)  (1<=i<=x),存下来就好

那么对于每个查询∑LCA(i, z)  (l<=i<=r),答案就是∑LCA(i, z)  (1<=i<=r) - ∑LCA(i, z)  (1<=i<=l-1)

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
vector<LL> G[50005];
typedef struct Res
{LL x;LL aim;LL id, t;bool operator < (const Res &b) const{if(x<b.x)return 1;return 0;}
}Res;
Res s[100005];
LL n, siz[50005], son[50005], dep[50005], fa[50005];
LL k, cnt, top[50005], rak[50005], id[50005], ans[50005][2], tre[222222], temp[222222];
void Sech1(LL u, LL p)
{LL i, v;fa[u] = p, dep[u] = dep[p]+1;siz[u] = 1;for(i=0;i<G[u].size();i++){v = G[u][i];if(v==p)continue;Sech1(v, u);siz[u] += siz[v];if(son[u]==0 || siz[v]>siz[son[u]])son[u] = v;}
}
void Sech2(LL u, LL p)
{LL v, i;top[u] = p;rak[u] = ++k, id[k] = u;if(son[u]==0)return;Sech2(son[u], p);for(i=0;i<G[u].size();i++){v = G[u][i];if(son[u]==v || fa[u]==v)continue;Sech2(v, v);}
}
void Update(LL l, LL r, LL x, LL a, LL b);
void Lazy(LL l, LL r, LL x);
LL Query(LL l, LL r, LL x, LL a, LL b);
void Tre_Update(LL x)
{while(x){Update(1, n, 1, rak[top[x]], rak[x]);x = fa[top[x]];}
}
LL Tre_Query(LL x)
{LL ans = 0;while(x){ans += Query(1, n, 1, rak[top[x]], rak[x]);x = fa[top[x]];}return ans;
}
int main(void)
{LL q, i, x, y, z, p;scanf("%lld%lld", &n, &q);for(i=2;i<=n;i++){scanf("%lld", &x);G[x+1].push_back(i);G[i].push_back(x+1);}Sech1(1, 0);Sech2(1, 1);for(i=1;i<=q;i++){scanf("%lld%lld%lld", &x, &y, &z);s[++cnt].id = i, s[cnt].aim = z+1, s[cnt].x = x, s[cnt].t = 0;s[++cnt].id = i, s[cnt].aim = z+1, s[cnt].x = y+1, s[cnt].t = 1;}sort(s+1, s+cnt+1);p = 1;for(i=1;i<=n;i++){Tre_Update(i);while(s[p].x<i)p++;while(s[p].x==i){ans[s[p].id][s[p].t] = Tre_Query(s[p].aim);p++;}}for(i=1;i<=q;i++)printf("%lld\n", (ans[i][1]-ans[i][0])%201314);return 0;
}void Lazy(LL l, LL r, LL x)
{LL m;m = (l+r)/2;tre[x*2] += temp[x]*(m-l+1);tre[x*2+1] += temp[x]*(r-m);if(l!=m)temp[x*2] += temp[x];if(r!=m+1)temp[x*2+1] += temp[x];temp[x] = 0;
}
void Update(LL l, LL r, LL x, LL a, LL b)
{LL m;if(l>=a && r<=b){tre[x] += r-l+1;if(l!=r)temp[x]++;return;}m = (l+r)/2;if(temp[x])Lazy(l, r, x);if(a<=m)Update(l, m, x*2, a, b);if(b>=m+1)Update(m+1, r, x*2+1, a, b);tre[x] = tre[x*2]+tre[x*2+1];
}
LL Query(LL l, LL r, LL x, LL a, LL b)
{LL m, sum = 0;if(l>=a && r<=b)return tre[x];m = (l+r)/2;if(temp[x])Lazy(l, r, x);if(a<=m)sum += Query(l, m, x*2, a, b);if(b>=m+1)sum += Query(m+1, r, x*2+1, a, b);return sum;
}

bzoj 3626: [LNOI2014]LCA(离线差分+树链剖分)相关推荐

  1. BZOJ 3626: [LNOI2014]LCA

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2074  Solved: 828 [Submit][Stat ...

  2. BZOJ - 3631 松鼠的新家 (树链剖分)

    题目链接 树链剖分基础题,路径权值修改+差分 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll ...

  3. 【bzoj 3531】 [Sdoi2014]旅行(树链剖分+树套树)

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 1197  Solved: 576 [Submit][Statu ...

  4. bzoj 4034: [HAOI2015]树上操作(树链剖分+线段树区间更新)

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 4981  Solved: 1603 [Submit][St ...

  5. BZOJ 3779 重组病毒 LCT,树链剖分,线段树

    题意: 给一棵树,每个点一开始颜色互不相同,支持三个操作                 1. 将一个点到根的路径染成一种新的颜色                 2. 将一个新的点设为根,并将原来的 ...

  6. bzoj 3730: 震波 动态点分治+树链剖分+线段树

    ##### 题目描述 : 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]. 不幸的是,这片土地常常发生地震,并且随 ...

  7. 树链剖分(轻重链)入门

    写在前面 仅想学树剖LCA的同学其实不必要了解线段树 前置知识:树形结构,链式前向星(熟练),线段树(熟练),DFS序(熟练),LCA(了解定义) 树链剖分(树剖):将树分解为一条条不相交的,从祖先到 ...

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

    显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案.观察到,深度其实就是上面有几个已 ...

  9. BZOJ3626 LNOI2014 LCA 树链剖分

    题意:给定一棵树,每次询问给出l r z,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和 题解: 显然,暴力求解的复杂度是无法承受的. 考虑这样的一种暴力,我们把 z 到根上的点全部打标 ...

最新文章

  1. ​你真正了解使用过的数据集吗?数据集有什么关系?数据集之间有多像?
  2. linux发行版_7款颜值当道的Linux发行版操作系统
  3. python处理excel表格-如何用python处理excel表格
  4. mysql 添加列,修改列,删除列
  5. java安装下载步骤_java下载安装教程
  6. PGIS中java程序授权问题
  7. Eucalyptus学习汇总
  8. 解决dos打开界面变小和打开软件字体乱码的问题
  9. 二十一世纪大学英语读写教程学习笔记(原文)——10 - Cloning: good Science or Baaaad Idea(克隆技术是好科学还是馊主意)
  10. 教你如何用Three.js创造一个三维太阳系
  11. java加密解密 pdf_Java加密与解密的艺术 梁栋著 中文 PDF版 [44M]
  12. Mac eclipse下载地址 Java开发
  13. 尚硅谷JavaWeb笔记——Filter过滤器(了解过滤器,看着一篇就够了)
  14. CryptoJS 下载地址
  15. HCNP学习笔记之OSPF邻接关系的建立和LSDB同步
  16. 怎样找回html里收藏的文件夹,电脑浏览器收藏的网址重装后如何找回
  17. 【中兴交换机MC-LAG配置】
  18. FPV无人机集训召集令~
  19. 嵌入式软件设计第十次实验报告-140201235-陈宇
  20. 产业区块链发展周报(10.17—10.23)| 陀螺研究院

热门文章

  1. python装饰器详解-python中的装饰器详解
  2. 人工智能趋势:语音识别发展前景广阔
  3. java sql注入正则表达式_php防止sql注入示例分析和几种常见攻击正则表达式
  4. 数学速算法64种口诀_小学数学有哪些数学计算技巧?
  5. Vue前后端交互实现图书管理功能
  6. 安装谷歌插件 ~ 一招轻松解决
  7. Vue登录注册,并保持登录状态
  8. cocos2d-x3.4 android重新编译,cocos2d-x 4.0 Spine 3.8编译环境配置(高级篇)
  9. html优化的基本网页布局,网站页面标题的SEO优化及布局要点
  10. win10samba服务器配置_win10访问samba配置共享目录,踩坑记