题目描述:

网址:http://www.lydsy.com/JudgeOnline/problem.php?id=3626
大意:
给出一个n个节点的有根树(编号为0到n-1,根节点为0)。
一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。
有q次询问,每次询问给出l r z,求\(∑dep[LCA(i,z)],{l<=i<=r}\)。
---(即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)

题目解法:

考虑求\(LCA(i,z)\),z是不变的。
那么如果把 \(i到root的路径\) 权值加1,最后答案就为 \(z到root路径\) 上的权值和。
这是一个常见的套路啦。
因为这个我们可以对每一次的询问进行差分。
查询答案变为\(Ans = Query(R) - Query(L-1);\)
这样就可以离线做:
我们从左往右依次增加 1~N到root的路径权值 ,然后 查询对应相关询问中 z到root路径 的权值和即可。
所有东西都直接用LCT维护即可。

实现代码

#include<bits/stdc++.h>
#define ll long long
#define RG register
#define IL inline
#define maxn 60000
#define mod 201314
using namespace std;

IL ll gi(){
    RG ll date = 0, m = 1;  RG char ch = 0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch = getchar();
    if(ch == '-'){m = -1; ch = getchar();}
    while(ch>='0' && ch<='9')
       {date=date*10+ch-'0'; ch = getchar();}
    return date*m;
}

ll N,Q,root; struct Question {ll L,R,Z;}qs[maxn];
ll ch[maxn][2],fa[maxn],rev[maxn],sum[maxn],sz[maxn],laz[maxn],val[maxn];
vector<ll>gpL[maxn],gpR[maxn]; ll stk[maxn]; 

IL bool Son(RG ll x){return ch[fa[x]][1] == x;}
IL bool Isroot(RG ll x){return (ch[fa[x]][1] != x && ch[fa[x]][0] != x);}
IL bool Reverse(RG ll x){swap(ch[x][0],ch[x][1]); rev[x]^=1;}
IL void PushUp(RG ll x){
    sum[x] = ( val[x] + sum[ch[x][0]] + sum[ch[x][1]] )%mod;
    sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
}
IL void PushDown(RG ll x){
    RG ll ls = ch[x][0],rs = ch[x][1];
    if(laz[x]){
        sum[ls] = (sum[ls] + 1ll*laz[x]*sz[ls])%mod;
        sum[rs] = (sum[rs] + 1ll*laz[x]*sz[rs])%mod;
        val[ls] = (val[ls] + laz[x])%mod;
        val[rs] = (val[rs] + laz[x])%mod;
        laz[ls] = (laz[x] + laz[ls])%mod;
        laz[rs] = (laz[x] + laz[rs])%mod;
        laz[x] = 0;
    }
    if(rev[x]){ Reverse(ls); Reverse(rs);rev[x] ^= 1; }
}

IL void Rot(RG ll x){
    RG ll y = fa[x],z = fa[y],c = Son(x);
    if(!Isroot(y))ch[z][Son(y)] = x; fa[x] = z;
    ch[y][c] = ch[x][!c]; fa[ch[y][c]] = y;
    ch[x][!c] = y; fa[y] = x; PushUp(y);
}
IL void Splay(RG ll x){
    stk[++stk[0]] = x;
    for(RG ll y = x; !Isroot(y); y = fa[y])stk[++stk[0]] = fa[y];
    while(stk[0])PushDown(stk[stk[0]--]);
    for(RG ll y = fa[x]; !Isroot(x); Rot(x),y = fa[x])
        if(!Isroot(y))Son(x) ^ Son(y) ? Rot(x) : Rot(y);
    PushUp(x);
}

IL void Access(RG ll x){ for(RG ll y = 0; x; y = x,x = fa[x])Splay(x),ch[x][1] = y,PushUp(x); }
IL void Makeroot(RG ll x){ Access(x); Splay(x); Reverse(x); }
IL void Split(RG ll x,RG ll y){ Makeroot(x); Access(y); Splay(y); }
IL void Link(RG ll x,RG ll y){ Makeroot(x); fa[x] = y; }

//已经把所有点的标号都加了1。
int main(){
    N = gi(); Q = gi();
    for(RG ll i = 1; i <= N; i ++)sz[i] = 1;
    for(RG ll i = 2; i <= N ; i ++)Link(gi()+1,i);
    for(RG ll i = 1; i <= Q ; i ++){
        qs[i].L = (gi()-1)+1; qs[i].R = gi()+1; qs[i].Z = gi()+1;
        gpL[qs[i].L].push_back(i);
        gpR[qs[i].R].push_back(i);
    }
    root = 1;
    for(RG ll i = 1; i <= N; i ++){
        Split(root,i);
        val[i]++; laz[i]++;
        sum[i] = sum[i] + sz[i];
        for(RG ll j = 0,c; j < gpL[i].size(); j ++)
            c = gpL[i][j] ,Split(root,qs[c].Z) , qs[c].L = sum[qs[c].Z];
        for(RG ll j = 0,c; j < gpR[i].size(); j ++)
            c = gpR[i][j] ,Split(root,qs[c].Z) , qs[c].R = sum[qs[c].Z];
    }
    for(RG ll i = 1; i <= Q; i ++)
        printf("%lld\n",(qs[i].R - qs[i].L + mod)%mod);
    return 0;
}

[LNOI2014] LCA的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. P4211 [LNOI2014]LCA

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

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

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

  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, ...

  10. [bzoj3626][LNOI2014]LCA

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

随机推荐

  1. WPF---Xaml中改变ViewModel的值

    在开发中遇到实现如下需求的情景:一个输入框,旁边一个清空输入的按钮,当输入框中有内容时显示清空按钮,点击该按钮可以清空输入框内容,当输入框中无内容时隐藏按钮 当然这个需求使用wpf的绑定功能很容易实现 ...

  2. 基于Parallax设计HTML视差效果

    年关将至,给大家拜年. 最近时间充裕了一点,给大家介绍一个比较有意思的控件:Parallax.它可以用来实现鼠标移动时,页面上的元素也做偏移的视差效果.在一些有表现层次,布局空旷的页面上,用来做Hea ...

  3. ubuntu16.04编译安装mysql-boost-5.7.21并编译成php扩展测试与使用

    我之前的文章已经改造了自定义MVC框架中的工具类(验证码,图片上传,图像处理,分类)4个类,接下来,就要改造模型类,模型类肯定要连接数据库,由于我的Ubuntu Linux是裸装的php(目前只编译了 ...

  4. Yii中DataProvider的使用

    1,DataProvider 什么是数据提供者 数据提供者可以获取数据,并提供给其他组件或页面使用 可以获得列的数据进行分页和排序 经常用来给数据小部件提供数据,方便用户互动地进行数据的分页与排序 实 ...

  5. POJ - 1190 生日蛋糕 dfs+剪枝

    思路:说一下最重要的剪枝,如果当前已经使用了v的体积,为了让剩下的表面积最小,最好的办法就是让R尽量大,因为V = πR 2H,A' = 2πRH,A' = V / R * 2 ,最大的R一定是取当前 ...

  6. hdu 1878 无向图的欧拉回路

    原题链接 hdu1878 大致题意: 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个无向图,问是否存在欧拉回路? 思路: 无向图存在欧拉回路的条件:1.图是连 ...

  7. UVA-804 模拟

    将每个translation的输入和输出place全部记录下来,模拟即可,当所有translation都不能工作时,就说明dead了. AC代码: #include<cstdio> #in ...

  8. php面试上机题(2018-3-3)

    需求:将第三方api的前3000条数据全部读取出来,存入对应的数据库字段 第三方api:http://pub.cloudmob.mobi/publisherapi/offers/?uid=92& ...

  9. keepalived双机热备nginx

    nginx目前是我最常用的反向代理服务,线上环境为了能更好的应对突发情况,一般会使用keepalived双机热备nginx或者使用docker跑nginx集群,keepalived是比较传统的方式,虽 ...

  10. 我的Java设计模式-单例模式

    就算不懂设计模式的兄弟姐妹们,想必也听说过单例模式,并且在项目中也会用上.但是,真正理解和熟悉单例模式的人有几个呢?接下来我们一起来学习设计模式中最简单的模式之一--单例模式 一.为什么叫单例模式? ...