洛谷$P4211\ [LNOI2014]\ LCA$ 树链剖分+线段树
正解:树剖+线段树
解题报告:
看到$dep[lca]$啥的就想到之前托腮腮$CSP$模拟$D1T3$的那个套路,,,
然后试下这个想法,于是$dep[lca(x,y)]=\sum_{i=1}^{\infty}[i\leq dep[lca(x,y)]]$,就可以是,从$x$到根全部加一然后查询$y$到根的权值和.
现在变成$\sum_{i=l}^r dep[lca(i,x)]$,那就$l$到$r$到根全加一然后查询$x$到根的权值和.
显然考虑差分呗?就$1$到$r$全加一的权值和减去$1$到$l-1$全加一的权值和.
于是就从$1$枚举到$n$每次从当前节点到根全加一,顺便维护下这个答案就完事$QwQ$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define lowbit(x) (x&(-x))
#define rg register
#define gc getchar()
#define ls(x) (x<<1)
#define rs(x) ((x<<1)|1)
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];~i;i=edge[i].nxt) const int N=+,mod=;
int n,q,dfn[N],sz[N],top[N],fa[N],as[N],hs[N],dfn_cnt,tr[N<<],ad[N<<];
vector<int>son[N];
struct node{int id,x,op;};
vector<node>V[N]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void add(ri &x,ri y){x+=y;if(x>=mod)x-=mod;if(x<)x+=mod;}
il void dfs1(ri x)
{
sz[x]=;ri siz=son[x].size();
rp(i,,siz-){dfs1(son[x][i]),sz[x]+=sz[son[x][i]];if(sz[son[x][i]]>sz[hs[x]])hs[x]=son[x][i];}
}
il void dfs2(ri x,ri tp)
{
top[x]=tp;dfn[x]=++dfn_cnt;if(hs[x])dfs2(hs[x],tp);ri siz=son[x].size();
rp(i,,siz-)if(son[x][i]^hs[x])dfs2(son[x][i],son[x][i]);
}
il void pushdown(ri x,ri l,ri r)
{
if(!ad[x])return;
ri mid=(l+r)>>;
add(tr[ls(x)],1ll*ad[x]*(mid-l+)%mod),add(tr[rs(x)],1ll*ad[x]*(r-mid)%mod);
ad[ls(x)]+=ad[x],ad[rs(x)]+=ad[x];ad[x]=;
}
void modify(ri x,ri l,ri r,ri to_l,ri to_r)
{
if(to_l<=l && r<=to_r){add(tr[x],r-l+);add(ad[x],);return;}
pushdown(x,l,r);
ri mid=(l+r)>>;if(mid>=to_l)modify(ls(x),l,mid,to_l,to_r);if(mid<to_r)modify(rs(x),mid+,r,to_l,to_r);
tr[x]=(tr[ls(x)]+tr[rs(x)])%mod;
}
int query(ri x,ri l,ri r,ri to_l,ri to_r)
{
if(to_l<=l && r<=to_r)return tr[x];
pushdown(x,l,r);ri mid=(l+r)>>,ret=;
if(mid>=to_l)ret=query(ls(x),l,mid,to_l,to_r);;if(mid<to_r)add(ret,query(rs(x),mid+,r,to_l,to_r));
return ret;
} int main()
{
freopen("4211.in","r",stdin);freopen("4211.out","w",stdout);
n=read();q=read();rp(i,,n)son[fa[i]=read()+].push_back(i);dfs1();dfs2(,);
rp(i,,q){ri l=read(),r=read()+,x=read()+;V[l].push_back((node){i,x,-});V[r].push_back((node){i,x,});}
rp(i,,n)
{
ri nw=i;while(nw)modify(,,n,dfn[top[nw]],dfn[nw]),nw=fa[top[nw]];
for(auto j:V[i])
{nw=j.x;while(nw)add(as[j.id],j.op*query(,,n,dfn[top[nw]],dfn[nw])),nw=fa[top[nw]];}
}
rp(i,,q)printf("%d\n",as[i]);
return ;
}
洛谷$P4211\ [LNOI2014]\ LCA$ 树链剖分+线段树的更多相关文章
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- 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 ...
随机推荐
- @codeforces - 1217F@ Forced Online Queries Problem
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 n 个点的无向图,标号从 1 到 n.一开始没有任何边 ...
- uda 1.C++ 函数
函数:Python vs C++ 在 Python 和 C++ 中,函数的作用相同:函数把语句组合在一起,执行某种任务.函数可以帮助你避免重复地复制和粘贴相同的代码. 函数编写的语法有些不同,主要有三 ...
- OpenResty,X-WAF防火墙相关
>>OpenResty<< >>Lua教程<< >>反向代理百度百科<< >>X-WAF配置指南<<
- Android图形子系统
图形操作可以有两种方式实现:一是利用通用CPU模拟图形操作:二是利用GPU专门做图形操作.前者会增加CPU的负担,在现在高分辨率已经是普遍现象的时候,让通用处理器来完成大量的图形计算已经不现实.And ...
- oracle用UNION替换OR (适用于索引列)
通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你 ...
- Springboot 2.x下多数据源配置
本文同样适用于2.x版本下Mybatis的多数据源配置 项目中经常会遇到一个项目需要访问多个数据源的情况,多数情况下可以参考这个教程进行配置. 不过该教程适合springboot1.x版本,由于2.x ...
- java 集合之HashMap的三种遍历
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. 这周我们只需记住三种遍历方法 1.通过keySet()获取键,再利用hashmap里面的.get(key)方法通过键获取 ...
- MySQL——修改视图
修改视图是指修改数据库中存在的视图,当基本表的某些字段发生变化时,可以通过修改视图来保持与基本表的一致性. 1. 用 CREATE OR REPLACE VIEW 语句修改视图 语法格式 ...
- ESB总线的核心架构
根据近期对开源ESB产品的研究,已经对Oracle和Tibco的ESB总线产品的实施经验积累,对ESB总线的核心产品架构有了进一步的清晰认识,将ESB的核心架构整理为上图,上图中看到的内容也是做为一款 ...
- element el-table 添加分页连接的序号,清除sortable排序
先看代码: <el-table :data="tableData" style="width: 100%" stripe size="mediu ...