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$里面去掉一个 ...
随机推荐
- GPU方法做倒排压缩和交集计算
之前一直想读这篇,今天读了一下,颇有收获: 1.对文档按相似term聚类之后,delta较小,能够提高压缩率(similarity graph) 1.GPU一般能够有几百个核,有shared memo ...
- 在Linux终端使用W3M浏览器下载文件
在Linux终端使用W3M浏览器下载文件 W3M 是3个基于Linux系统命令行的WEB网站浏览工具(w3m/Links/Lynx) 对于需要验证cookie 和来源的页面,比如163的超大附件,直接 ...
- 1.windows编程常用
1.画线 HDC hdc; hdc = ::GetDC(m_hWnd); ::MoveToEx(hdc, , , NULL); ::LineTo(hdc, , ); 2.填充矩形 HDC hdc; h ...
- Android程序测试
一.建立测试环境 安装了Android Developer Tools (ADT) 插件的Eclipse将为你创建,构建,以及运行Android程序提供一个基于图形界面的集成开发环境.Eclipse的 ...
- Linux常用PDF阅读软件
1.福昕阅读器是一款PDF文档阅读器,对中文的支持度非常高.福昕阅读器作为全球最流行的PDF阅读器,能够快速打开.浏览.审阅.注释.签署及打印任何PDF文件. 2.evince是一个支持多种格式的文件 ...
- Vijos——T 1082 丛林探险
https://vijos.org/p/1082 描述 东非大裂谷中有一片神秘的丛林,是全世界探险家的乐园,著名黄皮肤探险家BB一直想去试试.正好我国科学家2005年4月将首次对东非大裂谷进行科考,B ...
- .Net接口调试与案例
1.通过查看日志,可以看出问题的原因. 2.断点调试. 3.本地测试,确保无误后,线上测试. 4.输出测试. 通过get的方式,测试接口. // [HttpPost] public ActionRes ...
- vue --- 解读vue的中webpack.base.config.js
const path = require('path') const utils = require('./utils')// 引入utils工具模块,具体查看我的博客关于utils的解释,utils ...
- Yahoo!团队:网站性能优化的35条黄金守则(转)
Excetional Performance 团队总结出了一系列可以提高网站速度的方法.可以分为 7大类 35条.包括内容 .服务器 . CSS . JavaScript .Cookie .图片 .移 ...
- Repeater控件的
http://blog.csdn.net/zhang_xinxiu/article/details/21872433 想起来,公司的aspx页面前台数据展示除了datagrid以为还有Repeater ...