题目:传送门


这道题根本不用lca,也没有部分分。。。

考虑求两个点xy的lca的深度。

我们将x到树根所有点的值都加1,然后查询y到根的和,其实就是lca的深度。

所以本题离线一下上树剖乱搞就可以了。


AC代码如下:
718ms 17348Kib

 #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; namespace StandardIO { template<typename T> inline void read (T &x) {
x=;T f=;char c=getchar();
for (; c<''||c>''; c=getchar()) if (c=='-') f=-;
for (; c>=''&&c<=''; c=getchar()) x=x*+c-'';
x*=f;
}
template<typename T> inline void write (T x) {
if (x<) putchar('-'),x=-x;
if (x>=) write(x/);
putchar(x%+'');
} } using namespace StandardIO; namespace Solve { const int MOD=;
const int N=; struct Tree {
int tree[N*],tag[N*];
void pushdown (int pos,int left,int right) {
if (tag[pos]) {
int mid=(left+right)/;
tree[pos*]+=(mid-left+)*tag[pos],tree[pos*]%=MOD;
tree[pos*+]+=(right-mid)*tag[pos],tree[pos*+]%=MOD;
tag[pos*]+=tag[pos],tag[pos*+]+=tag[pos],tag[pos*]%=MOD,tag[pos*+]%=MOD;
tag[pos]=;
}
}
void pushup (int pos) {
tree[pos]=tree[pos*]+tree[pos*+],tree[pos]%=MOD;
}
void update (int pos,int left,int right,int L,int R,int add) {
if (L<=left&&right<=R) {
tree[pos]+=add*(right-left+),tree[pos]%=MOD;
tag[pos]+=add,tag[pos]%=MOD;
return;
}
pushdown(pos,left,right);
int mid=(left+right)/;
if (L<=mid) update(pos*,left,mid,L,R,add);
if (R>mid) update(pos*+,mid+,right,L,R,add);
pushup(pos);
}
int query (int pos,int left,int right,int L,int R) {
if (L<=left&&right<=R) return tree[pos];
pushdown(pos,left,right);
int mid=(left+right)/;
int ans=;
if (L<=mid) ans+=query(pos*,left,mid,L,R),ans%=MOD;
if (R>mid) ans+=query(pos*+,mid+,right,L,R),ans%=MOD;
return ans;
}
} ljz;
int n,q;
vector<int>M[N];
int dep[N],siz[N],fa[N],son[N];
int ind[N],cnt;
int top[N]; void dfs1 (int now,int father) {
dep[now]=dep[father]+,fa[now]=father,siz[now]=;
for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) {
if(*i==father) continue;
dfs1(*i,now);
siz[now]+=siz[*i];
if (siz[*i]>siz[son[now]]) son[now]=*i;
}
}
void dfs2(int now,int tp){
top[now]=tp,ind[now]=++cnt;
if (son[now]) dfs2(son[now],tp);
for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) {
if (*i==fa[now]||*i==son[now]) continue;
dfs2(*i,*i);
}
}
void upd (int x,int add){
while (x) {
ljz.update(,,n,ind[top[x]],ind[x],add);
x=fa[top[x]];
}
}
int que (int x) {
int ans=;
while (x) {
ans+=ljz.query(,,n,ind[top[x]],ind[x]),ans%=MOD;
x=fa[top[x]];
}
return ans;
}
int A[N];
struct Q{
int val,ind;
Q () {val=ind=;}
Q (int a,int b) :val(a),ind(b) {}
friend bool operator < (Q a,Q b) {
return a.val<b.val;
}
} s1[N],s2[N];
int a1=,a2=;
int Ans[N]; inline void solve () {
read(n),read(q);
for (register int i=; i<=n; i++) {
int a;
read(a);
M[a+].push_back(i);
}
dfs1(,);
dfs2(,);
for (register int i=; i<=q; i++) {
int a,b,c;
read(a),read(b),read(c);
a++,b++,c++;
A[i]=c;
s1[i]=Q(a-,i),s2[i]=Q(b,i);
}
sort(s1+,s1+q+);
sort(s2+,s2+q+);
while (s1[a1].val==) a1++;
for (register int i=; i<=n; i++) {
upd(i,);
while (s1[a1].val==i) {
Ans[s1[a1].ind]-=que(A[s1[a1].ind])-MOD,Ans[s1[a1].ind]%=MOD;
a1++;
}
while (s2[a2].val==i) {
Ans[s2[a2].ind]+=que(A[s2[a2].ind]),Ans[s2[a2].ind]%=MOD;
a2++;
}
}
for (register int i=; i<=q; i++) {
write(Ans[i]),putchar('\n');
}
} } using namespace Solve; int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
solve();
}

题解 LNOI2014 LCA的更多相关文章

  1. 【BZOJ3626】[LNOI2014]LCA 离线+树链剖分+线段树

    [BZOJ3626][LNOI2014]LCA Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度 ...

  2. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  3. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status ...

  4. bzoj 3626: [LNOI2014]LCA 离线+树链剖分

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 426  Solved: 124[Submit][Status] ...

  5. BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )

    说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...

  6. 洛谷 P4211 [LNOI2014]LCA 解题报告

    [LNOI2014]LCA 题意 给一个\(n(\le 50000)\)节点的有根树,询问\(l,r,z\),求\(\sum_{l\le i\le r}dep[lca(i,z)]\) 一直想启发式合并 ...

  7. P4211 [LNOI2014]LCA

    P4211 [LNOI2014]LCA 链接 分析: 首先一种比较有趣的转化是,将所有点到1的路径上都+1,然后z到1的路径上的和,就是所有答案的deep的和. 对于多次询问,要么考虑有把询问离线,省 ...

  8. P4211 [LNOI2014]LCA LCT

    P4211 [LNOI2014]LCA 链接 loj luogu 思路 多次询问\(\sum\limits_{l \leq i \leq r}dep[LCA(i,z)]\) 可以转化成l到r上的点到根 ...

  9. [BZOJ3626] [LNOI2014]LCA(树链剖分)

    [BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...

随机推荐

  1. 【BZOJ3309】DZY Loves Math - 莫比乌斯反演

    题意: 对于正整数n,定义$f(n)$为$n$所含质因子的最大幂指数.例如$f(1960)=f(2^3 * 5^1 * 7^2)=3$,$f(10007)=1$,$f(1)=0$. 给定正整数$a,b ...

  2. NOIP2015 运输计划 (树上差分+二分答案)

    ---恢复内容开始--- 题目大意:给你一颗树,你可以把其中一条边的边权改成0,使给定的一些树链的权值和的最大值最小 把lenth定义为未修改边权时的答案 考虑二分答案,如果二分的答案成立,设修改成0 ...

  3. linux内存随笔

    内存在电脑中使用广泛,比如内存条内存.显卡显存.cpu缓存.raid卡缓存等,缓存就是数据交换的缓冲区(称作cache),缓存往往都是RAM(断电文件丢失),他们的读写速率非常高,用来帮助硬件更快的响 ...

  4. python hashlib、configparse、logging

    一.hashlib 1.Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等.     2.摘要算法 通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目 ...

  5. Ubuntu下安装curl和corn

    Ubuntu下安装curl sudo apt install curl Ubuntu下安装cron apt-get install cron

  6. STM32 GPIO重映射(转)

    重映射就是将引脚功能重新定义到其他引脚, 例如PA9是USART1-TX默认的 管脚,但是现在PA9用做它用了,那可以将USART1-TX重新映射到PB6,当然这 种映射不是随意的想映射到哪个脚就哪个 ...

  7. tp 在Nginx上各种404

    对于ThinkPHP的URL访问路劲如:http://域名/index.php/Index/BlogTest/read,原先的Nginx的是不支持的pathinfo路劲的,导致你在thinkPHP5上 ...

  8. C#-入门思维导图

    C#-入门思维导图 百度云盘 链接:http://pan.baidu.com/s/1jI5zMS2 密码:0ypc 如有错误,请告知我

  9. map和multimap映射容器

    map容器 map所处理的数据与数据库表具有键值的记录非常相似,在键值与映射数据之间,建立一个数学上的映射关系.map容器的数据结构仍然採用红黑树进行管理.插入的元素键值不同意反复,所使用的结点元素的 ...

  10. Asp.net动态页面静态化之初始NVelocity模板引擎

    Asp.net动态页面静态化之初始NVelocity模板引擎 静态页面是网页的代码都在页面中,不须要运行asp,php,jsp,.net等程序生成client网页代码的网页,静态页面网址中一般不含&q ...