并不对劲的bzoj3626:loj2558:p4211:[LNOI2014]LCA
题目大意
有一棵有\(n\)(\(n\leq5*10^4\))个点的树,\(q\)(\(q\leq5*10^4\))次询问,每次给出\(l,r,x\)表示询问所有编号在\([l,r]\)的点与点\(x\)的LCA的深度之和
题解
将\([l,r]\)里每个点和该点的所有祖先点权+1后,查询点\(x\)和它的祖先的点权和就行了
可持久化线段树维护
代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k])
#define maxn 50010
#define ls (son[u][0])
#define rs (son[u][1])
#define lsa son[ua][0]
#define rsa son[ua][1]
#define lsb son[ub][0]
#define rsb son[ub][1]
#define mi (l+r>>1)
#define LL long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
const int mod=201314;
int n,q,rt[maxn],tr[maxn<<7],mk[maxn<<7],son[maxn<<7][2],ver[maxn<<7],fir[maxn],nxt[maxn],v[maxn],cnt,fa[maxn];
int dfn[maxn],tim,wson[maxn],siz[maxn],top[maxn],cntnd;
void ade(int u1,int v1){v[cnt]=v1,nxt[cnt]=fir[u1],fir[u1]=cnt++;}
void getsiz(int u)
{
siz[u]=1;
view(u,k)if(v[k]!=fa[u])
{
getsiz(v[k]),siz[u]+=siz[v[k]];
if(siz[v[k]]>siz[wson[u]])wson[u]=v[k];
}
}
void gettop(int u,int anc)
{
top[u]=anc,dfn[u]=++tim;
if(wson[u])gettop(wson[u],anc);
view(u,k)if(v[k]!=fa[u]&&v[k]!=wson[u])gettop(v[k],v[k]);
}
int mo(int x){if(x>=mod)return x-mod;if(x<0)return x+mod;return x;}
int build(int l,int r)
{
int u=++cntnd;
if(l==r){return u;}
ls=build(l,mi),rs=build(mi+1,r);
return u;
}
int add(int u,int l,int r,int x,int y,int vers)
{
int nu=vers==ver[u]?u:++cntnd;
if(x<=l&&r<=y){son[nu][0]=ls,son[nu][1]=rs,ver[nu]=vers,tr[nu]=mo(tr[u]+r-l+1),mk[nu]=mo(mk[u]+1);return nu;}
ver[nu]=vers,tr[nu]=mo(tr[u]+y-x+1),mk[nu]=mk[u];
if(x<=mi)son[nu][0]=add(ls,l,mi,x,min(mi,y),vers);
else son[nu][0]=ls;
if(y>mi)son[nu][1]=add(rs,mi+1,r,max(x,mi+1),y,vers);
else son[nu][1]=rs;
return nu;
}
int ask(int ua,int ub,int l,int r,int x,int y,int ad)
{
if(x<=l&&r<=y){return mo(mo(tr[ua]-tr[ub])+(LL)ad*(LL)(y-x+1)%mod);}
int lans=0,rans=0;
if(x<=mi)lans=ask(lsa,lsb,l,mi,x,min(mi,y),mo(ad+mo(mk[ua]-mk[ub])));
if(y>mi)rans=ask(rsa,rsb,mi+1,r,max(x,mi+1),y,mo(ad+mo(mk[ua]-mk[ub])));
return mo(lans+rans);
}
int main()
{
memset(fir,-1,sizeof(fir));
n=read(),q=read();
rep(i,2,n)fa[i]=read()+1,ade(fa[i],i);
getsiz(1),gettop(1,1);rt[0]=build(1,n);
rep(i,1,n)
{
rt[i]=rt[i-1];int x=i;
while(top[x]!=1){rt[i]=add(rt[i],1,n,dfn[top[x]],dfn[x],i);x=fa[top[x]];}
rt[i]=add(rt[i],1,n,1,dfn[x],i);
}
while(q--)
{
int l=read()+1,r=read()+1,x=read()+1,ans=0;
while(top[x]!=1){ans=mo(ans+ask(rt[r],rt[l-1],1,n,dfn[top[x]],dfn[x],0));x=fa[top[x]];}
ans=mo(ans+ask(rt[r],rt[l-1],1,n,1,dfn[x],0));
write(ans);
}
return 0;
}
并不对劲的bzoj3626:loj2558:p4211:[LNOI2014]LCA的更多相关文章
- P4211 [LNOI2014]LCA
P4211 [LNOI2014]LCA 链接 分析: 首先一种比较有趣的转化是,将所有点到1的路径上都+1,然后z到1的路径上的和,就是所有答案的deep的和. 对于多次询问,要么考虑有把询问离线,省 ...
- P4211 [LNOI2014]LCA LCT
P4211 [LNOI2014]LCA 链接 loj luogu 思路 多次询问\(\sum\limits_{l \leq i \leq r}dep[LCA(i,z)]\) 可以转化成l到r上的点到根 ...
- 洛谷 P4211 [LNOI2014]LCA 解题报告
[LNOI2014]LCA 题意 给一个\(n(\le 50000)\)节点的有根树,询问\(l,r,z\),求\(\sum_{l\le i\le r}dep[lca(i,z)]\) 一直想启发式合并 ...
- 洛谷 P4211 [LNOI2014]LCA (树链剖分+离线)
题目:https://www.luogu.org/problemnew/solution/P4211 相当难的一道题,其思想难以用言语表达透彻. 对于每个查询,区间[L,R]中的每个点与z的lca肯定 ...
- [火星补锅] 非确定性有穷状态决策自动机练习题Vol.3 T3 && luogu P4211 [LNOI2014]LCA 题解
前言: 这题感觉还是很有意思.离线思路很奇妙.可能和二次离线有那么一点点相似?当然我不会二次离线我就不云了. 解析: 题目十分清真. 求一段连续区间内的所有点和某个给出的点的Lca的深度和. 首先可以 ...
- Luogu P4211 [LNOI2014]LCA
我去这道题的Luogu评级是假的吧,这都算黑题. 我们首先考虑把操作离线不强制在线的题目离线一下一般都要方便些 考虑差分,我们用\(f(x)\)表示\([1,x]\)之间的点与\(z\)的答案,那么显 ...
- 洛谷$P4211\ [LNOI2014]\ LCA$ 树链剖分+线段树
正解:树剖+线段树 解题报告: 传送门$QwQ$ 看到$dep[lca]$啥的就想到之前托腮腮$CSP$模拟$D1T3$的那个套路,,, 然后试下这个想法,于是$dep[lca(x,y)]=\sum_ ...
- 【BZOJ3626】[LNOI2014]LCA 离线+树链剖分+线段树
[BZOJ3626][LNOI2014]LCA Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度 ...
- [BZOJ3626] [LNOI2014]LCA(树链剖分)
[BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...
随机推荐
- 使用RMAN恢复数据库
使用RMAN恢复数据库 由于需要搭建一个测试环境,把上周末的一个全备拿出来做恢复,首先备份一下测试库上现有的重要表: exp banping/bangping@ERPTEST file=f:\2009 ...
- bzoj3875 【Ahoi2014】骑士游戏 spfa处理后效性动规
骑士游戏 [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻 ...
- Linux(1):基本配置
linux里面的网络(网卡)配置: 1. 输出 setup 命令进行设置 2. 选择 "Network configuration" ,按 回车键 3. 选择 "Devi ...
- 细胞分裂(洛谷 P1069)
题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家.现在,他正在为一个细胞实 验做准备工作:培养细胞样本. Hanks 博士手里现在有 N 种细胞,编号从 1~N,一个 ...
- PatentTips - Solid State Memory Wear Leveling
BACKGROUND OF THE INVENTION Solid-state memory devices encompass rewritable non-volatile memory devi ...
- Lca 之倍增算法
引入: 比如说要找树上任意两个点的路上的最大值.如果是一般的做法 会 接近o(n)的搜,从一个点搜到另一个点,但是如果询问多了复杂度就很高了. 然后我们会预处理.预处理是o(n²)的,询问是o(1)的 ...
- Oracle: 通过命令行下载安装文件
1. 导出oracle cookies 参考:https://blog.pythian.com/how-to-download-oracle-software-using-wget-or-curl/ ...
- Meteor check
check方法用于检查参数或类型是否匹配模式. 安装check包 打开命令提示符窗口,并安装该软件包. C:\Users\Administrator\Desktop\meteorApp>mete ...
- 使用引导光盘,将你的PC变身瘦客户机
很多国内使用VMware View桌面虚拟化产品的朋友问我,是否可以将自己现有的PC改造成一台瘦客户机呢? 一方面即可以得到桌面虚拟化的管理,安全的好处,而且连前端PC机的系统管理的工作都省了? 答案 ...
- 【Nginx】Hello world程序
模块如何在运行中生效 配置文件中的location块决定了匹配某种URL的请求将会由相应的HTTP模块处理,因此,运行时HTTP框架会在接收完毕HTTP请求的头部后,将请求的URL与配置文件中的所有l ...