BZOJ3626 [LNOI2014]LCA 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ3626
题意概括
给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。
有q次询问,每次询问给出l r z,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和
题解
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <vector>
using namespace std;
const int N=50005,mod=201314;
struct Gragh{
int cnt,y[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,q,cnp=0,ans[N],L[N],R[N],wn[N];
int fa[N],son[N],depth[N],size[N],top[N],p[N],ap[N];
vector <int> bh[N];
struct Tree{
int v,add,size;
}t[N*4];
void Get_Gen_Info(int rt,int pre,int d){
depth[rt]=d,fa[rt]=pre,size[rt]=1,son[rt]=-1;
for (int i=g.fst[rt];i;i=g.nxt[i])
if (g.y[i]!=pre){
int s=g.y[i];
Get_Gen_Info(s,rt,d+1);
size[rt]+=size[s];
if (son[rt]==-1||size[s]>size[son[rt]])
son[rt]=s;
}
}
void Get_Top(int rt,int tp){
top[rt]=tp;
ap[p[rt]=++cnp]=rt;
if (son[rt]==-1)
return;
Get_Top(son[rt],tp);
for (int i=g.fst[rt];i;i=g.nxt[i]){
int s=g.y[i];
if (s!=fa[rt]&&s!=son[rt])
Get_Top(s,s);
}
}
void pushup(int rt){
int ls=rt<<1,rs=ls|1;
t[rt].v=t[ls].v+t[rs].v;
}
void build(int rt,int le,int ri){
t[rt].add=t[rt].v=0,t[rt].size=ri-le+1;
if (le==ri)
return;
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
build(ls,le,mid);
build(rs,mid+1,ri);
}
void pushdown(int rt){
int ls=rt<<1,rs=ls|1,&a=t[rt].add;
if (a){
t[ls].add+=a,t[ls].v+=a*t[ls].size;
t[rs].add+=a,t[rs].v+=a*t[rs].size;
a=0;
}
}
void update(int rt,int le,int ri,int xle,int xri,int v){
if (xle>ri||xri<le)
return;
if (xle<=le&&ri<=xri){
t[rt].v+=v*t[rt].size;
t[rt].add+=v;
return;
}
pushdown(rt);
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
update(ls,le,mid,xle,xri,v);
update(rs,mid+1,ri,xle,xri,v);
pushup(rt);
}
int query(int rt,int le,int ri,int xle,int xri){
if (xle>ri||xri<le)
return 0;
if (xle<=le&&ri<=xri)
return t[rt].v;
pushdown(rt);
int mid=(le+ri)>>1,ls=rt<<1,rs=ls|1;
return query(ls,le,mid,xle,xri)+query(rs,mid+1,ri,xle,xri);
}
void Tupdate(int a){
int f=top[a];
while (a){
update(1,1,n,p[f],p[a],1);
a=fa[f],f=top[a];
}
}
int Tquery(int a){
int f=top[a],ans=0;
while (a){
ans+=query(1,1,n,p[f],p[a]);
a=fa[f],f=top[a];
}
return ans;
}
int main(){
scanf("%d%d",&n,&q);
for (int i=1,a;i<n;i++){
scanf("%d",&a);
g.add(a+1,i+1);
g.add(i+1,a+1);
}
Get_Gen_Info(1,0,0);
Get_Top(1,1);
build(1,1,n);
for (int i=0;i<=n;i++)
bh[i].clear();
for (int i=1;i<=q;i++){
scanf("%d%d%d",&L[i],&R[i],&wn[i]);
L[i]++,R[i]++,wn[i]++;
bh[L[i]-1].push_back(i);
bh[R[i]].push_back(i);
}
memset(ans,0,sizeof ans);
for (int i=1;i<=n;i++){
Tupdate(i);
for (int j=0;j<bh[i].size();j++){
int k=bh[i][j];
if (i==L[k]-1)
ans[k]-=Tquery(wn[k]);
else
ans[k]+=Tquery(wn[k]);
}
}
for (int i=1;i<=q;i++)
printf("%d\n",ans[i]%mod);
return 0;
}
BZOJ3626 [LNOI2014]LCA 树链剖分 线段树的更多相关文章
- 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 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 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ3862Little Devil I——树链剖分+线段树
题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...
- BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树
题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...
- BZOJ2819Nim——树链剖分+线段树+Nim游戏
题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- [HDU3710] Battle Over Cities [树链剖分+线段树+并查集+kruskal+思维]
题面 一句话题意: 给定一张 N 个点, M 条边的无向连通图, 每条边上有边权 w . 求删去任意一个点后的最小生成树的边权之和. 思路 首先肯定要$kruskal$一下 考虑$MST$里面去掉一个 ...
随机推荐
- pyqt5 添加属性-类方法用属性形式访问
方法一 装饰器法 import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout,QLab ...
- luogu P2508 [HAOI2008]圆上的整点
传送门 推荐去bzoj看个视频了解一下 不要妄想视频直接告诉你题解 但是视频告诉了你后面要用的东西 首先我们要求的是\(x^2+y^2=n^2(x,y\in Z)\)的\((x,y)\)对数,可以转化 ...
- PHP二叉树
<?php /******************************************************** * 我写的PHP都是从C语言的数据结构中演化而来********* ...
- TDateTimePicker 选择最小日期时异常处理
TDateTimePicker 控件属性窗体选择最小日期,运行时选择时可以看到的最小的日期,但是选择最小时就异常 :date is less than minimum of *** 解决过程 ...
- input框的输入限制
1.输入数字 <input onKeyUp="value=value.replace(/[^\d|chun]/g,'')"> 2.只输入中文 <input typ ...
- 基于URL的权限管理(三)
思路:先创建一个专门的类ActiveUser用于存储用户登录的信息,主要用于存储用户id,账户,名称,菜单,权限. 认证拦截器主要是查看用户是否已登陆,如果没有转发到登陆界面,用户用账户跟密码登录时候 ...
- nginx反向代理实现前后端分离&跨域问题
1.代理和跨域 1.1 正向代理 1)用户希望代理服务器帮助其和要访问服务器之间实现通信,需要: a.用户IP报文的目的IP=代理服务器IP: b.用户报文端口号=代理服务器监听端口号: c.HTTP ...
- Jetson tk1 安装 usbtoserials 驱动(重新刷机)
一.tk1驱动包,文件系统和源码下载 截止2016年9月1号,tk1最版本为R21.5. (以下三个文件放在同一个文件夹下) 1.driver package(驱动包,相当于安装程序) https:/ ...
- Linq基于两个属性的分组
1.需求 我们看下面的定义 #region 学生类 /// <summary> /// 学生类 /// </summary> class Student { /// <s ...
- 【CTF WEB】ISCC 2016 web 2题记录
偶然看到的比赛,我等渣渣跟风做两题,剩下的题目工作太忙没有时间继续做. 第1题 sql注入: 题目知识 考察sql注入知识,题目地址:http://101.200.145.44/web1//ind ...