BZOJ3626: [LNOI2014]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
解题思路:
蒟蒻QAQ的我一开始以为是树上莫队。
还好吧,这题其实是将Deep重新理解了一下,就是从根到这个点的距离。
我们发现可以在树链上(到1)加一,最后查询到根的权值和。
发现具有区间可减性。
线段树+树剖搞定。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
typedef long long lnt;
const lnt mod=;
using std::sort;
struct trnt{
lnt lzt;
lnt val;
}tr[];
struct pnt{
int hd;
int fa;
int tp;
int dp;
int no;
int wgt;
int ind;
int mxs;
}p[];
struct ent{
int twd;
int lst;
}e[];
int ans[];
struct data{
int no;
bool lft;
int rgt;
int z;
}dt[];
int cnt;
int dfn;
int n,q;
bool cmp(data x,data y)
{
return x.rgt<y.rgt;
}
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void add(int l,int r,int spc,lnt x)
{
if(!spc)
return ;
tr[spc].lzt=(tr[spc].lzt+x)%mod;
tr[spc].val=(tr[spc].val+(((lnt)(r-l+))*x)%mod)%mod;
return ;
}
void pushdown(int spc,int l,int r)
{
if(tr[spc].lzt)
{
int mid=(l+r)>>;
add(l,mid,lll,tr[spc].lzt);
add(mid+,r,rrr,tr[spc].lzt);
tr[spc].lzt=;
}
return ;
}
void pushup(int spc)
{
tr[spc].val=(tr[lll].val+tr[rrr].val)%mod;
}
void update(int l,int r,int ll,int rr,int spc,lnt v)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
{
add(l,r,spc,v);
return ;
}
pushdown(spc,l,r);
int mid=(l+r)>>;
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
lnt query(int l,int r,int ll,int rr,int spc)
{
if(ll>r||l>rr)
return 0ll;
if(ll<=l&&r<=rr)
return tr[spc].val;
int mid=(l+r)>>;
pushdown(spc,l,r);
return (query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr))%mod;
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(p[to].wgt>maxs)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].ind=++dfn;
p[x].tp=top;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
return ;
}
void Insert(int x)
{
while(p[x].tp!=)
{
update(,n,p[p[x].tp].ind,p[x].ind,,);
x=p[p[x].tp].fa;
}
update(,n,,p[x].ind,,);
return ;
}
lnt Val(int x)
{
lnt ansl=;
while(p[x].tp!=)
{
ansl+=query(,n,p[p[x].tp].ind,p[x].ind,);
ansl%=mod;
x=p[p[x].tp].fa;
}
ansl+=query(,n,,p[x].ind,);
ansl%=mod;
return ansl;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
int a;
scanf("%d",&a);
a++;
ade(a,i);
ade(i,a);
}
cnt=;
for(int i=;i<=q;i++)
{
int tmp;
cnt++;
dt[cnt].no=i;
dt[cnt].lft=true;
scanf("%d",&dt[cnt].rgt);
cnt++;
dt[cnt].no=i;
dt[cnt].lft=false;
scanf("%d",&dt[cnt].rgt);
dt[cnt].rgt++;
scanf("%d",&tmp);
tmp++;
dt[cnt].z=dt[cnt-].z=tmp;
}
sort(dt+,dt+cnt+,cmp);
Basic_dfs(,);
Build_dfs(,);
int plc=;
for(int i=;i<=cnt;i++)
{
while(plc<=dt[i].rgt)
{
Insert(plc);
plc++;
}
int x=dt[i].no;
int pl=dt[i].z;
lnt tmp=Val(pl);
if(dt[i].lft)
tmp=-tmp;
ans[x]=(ans[x]+tmp)%mod;
}
for(int i=;i<=q;i++)
printf("%lld\n",(ans[i]%mod+mod)%mod);
return ;
}
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$里面去掉一个 ...
随机推荐
- Service绑定模式
Service绑定模式 使用绑定的Service能够实现组件与Service的通信. 组件与被绑定的Service能够不归属于同一个应用程序.因此通过绑定Service能够实现进程间通信. ...
- 制作自己的特色PE----Mr.Zhang
必备的文件和工具 win7.iso/win8.iso Windows系统ISO镜像 WimTool BOOT.WIM文件的改动 RegWorkShop 注冊表编辑和分析利器 UltraISO 改动wi ...
- mysql 5.6 安装教程
首先是下载 mysql-installer-community-5.6.14.0.msi ,大家可以到 mysql 官方网去下载,也可以到笔者所提供的地址去下载,下载方法在这里就不多说了,我想大家都明 ...
- jQuery.inArray和splice删除数组元素
不知道数组下标的情况下,删除数组对应元素.实例: var arrays = ['a','b','c','d']; arrays.splice($.inArray('c',arrays),1); ale ...
- 【2017 Multi-University Training Contest - Team 1 1011】KazaQ's Socks
[Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6043 [Description] 一个人壁橱里有n双袜子,每天早上取一双最小下标的袜子,然后晚上放 ...
- Android基于XMPP Smack及Openfire学习笔记(1)
之前开发的项目中实用到IM聊天功能.可是这块功能公司有专门的IM团队来开发,由他们开发好后.直接接入到我们APP中.我參与写IM相关功能非常地少,所以也一直想学习相关知识 . 眼下Android主要用 ...
- [Python] isinstance() for checking object type
isinstance("foo", str) isinstance(1, int) isinstance(4.0, float)
- iOS 平台上常见的安装包有三种,deb、ipa 和 pxl
前言:目前 iOS 平台上常见的安装包有三种,deb.ipa 和 pxl. 其中 deb 格式是 Debian 系统(包含 Debian 和 Ubuntu )专属安装包格式,配合 APT 软件管理系统 ...
- openssl之BIO系列之25---结束语
(作者:DragonKing, Mail: wzhah@263.net ,公布于:http://openssl.126.com之ope nssl专业论坛) 经过半个月左右,最终将BIO的结构和各个分支 ...
- java基本的语法
Java语言发展史 课程大纲: Java语言发展史: 1.sun公司1995年推出,2009年Oracle公司收购sun: 下载: 1.到Oracle官网下载 Java体系与特点 课程大纲: J ...