我们可以思考怎么做呢。

首先我们需要进行一些分类讨论:

我们先思考一下如果所有关键点都在 \(p\) 的子树内,

那显然是所有关键点的 \(Lca\) 到 \(p\) 距离。

如果所有关键点一些在 \(p\) 的子树里,一些在子树外,则答案显然为 \(0\)。

那我们只需要接着讨论一下所有关键点在都在子树外的情况即可。

我们知道一个点一定会沿着祖先往下走,然后在往一个子树进入。

如果关键点全都是在祖先的一个子树内,那答案一定是这些关键点的 \(Lca\) 和 \(p\) 的距离。

否则这个答案一定是到祖先的链上的某个点,这个点满足是这个子树里有关键点且是最深的点。

区间 \(Lca\) 可以使用线段树解决,然后我们在 \(dfn\) 序上做一个主席树的操作,然后就可以查询子树内的点的情况了。

// code by fhq_treap
#include<bits/stdc++.h>
#define ll int
#define N 300005 inline ll read(){
char C=getchar();
ll A=0 , F=1;
while(('0' > C || C > '9') && (C != '-')) C=getchar();
if(C == '-') F=-1 , C=getchar();
while('0' <= C && C <= '9') A=(A << 1)+(A << 3)+(C - 48) , C=getchar();
return A*F;
} template <typename T>
void write(T x)
{
if(x < 0) {
putchar('-');
x = -x;
}
if(x > 9)
write(x/10);
putchar(x % 10 + '0');
return;
} ll n,q;
ll head[N],cnt;
struct P{
int to,next,w;
}e[N << 1];
inline void add(int x,int y,int w){
e[++cnt].to = y,e[cnt].next = head[x],e[cnt].w = w,head[x] = cnt;
} //tree ll dfn[N],s[N],inv[N];
ll dfncnt;
int fa[N][30],dep[N],end[N];
inline void dfs(int x,int f){
end[x] = dfn[x] = ++dfncnt;
dep[x] = dep[f] + 1;
inv[dfncnt] = x;
fa[x][0] = f;
for(int i = 1;i < 30;i ++)
fa[x][i] = fa[fa[x][i - 1]][i - 1];
for(int i = head[x];i;i = e[i].next){
int v = e[i].to;
if(v == f)continue;
s[v] = s[x] + e[i].w;
dfs(v,x);
end[x] = std::max(end[x],end[v]);
}
} inline ll lca(ll x,ll y){
if(dep[y] > dep[x])
std::swap(x,y);
for(int i = 29;i >= 0;--i){
if(dep[fa[x][i]] >= dep[y])
x = fa[x][i];
}
if(x == y)
return x;
for(int i = 29;i >= 0;--i){
if(fa[x][i] != fa[y][i])
x = fa[x][i],y = fa[y][i];
}
return fa[x][0];
} ll T[N << 2]; #define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
#define mid ((l + r) >> 1)
#define root 1,1,n inline void build(int u,int l,int r){
if(l == r){
T[u] = l;·1全额日图与i哦怕【-】
return ;
}
build(ls(u),l,mid);
build(rs(u),mid + 1,r);
T[u] = lca(T[ls(u)],T[rs(u)]);
return ;
} inline ll qlca(int u,int l,int r,int tl,int tr){
if(tl <= l && r <= tr)
return T[u];
ll li,ri;li = ri = 0;
if(tl <= mid)
li = qlca(ls(u),l,mid,tl,tr);
if(tr > mid)
ri = qlca(rs(u),mid + 1,r,tl,tr);
return (li && ri) ? lca(li,ri) : li + ri;
} //dfn_lca int H[N * 40];
int Hcnt;
int Head[N],Ls[N * 40],Rs[N * 40];
inline void merge(int las,int &now,int p,int l,int r){
if(!now)now = ++Hcnt;
Ls[now] = Ls[las];
Rs[now] = Rs[las];
H[now] = H[las] + 1;
if(l == r)
return ;
if(p <= mid){
Ls[now] = 0;
merge(Ls[las],Ls[now],p,l,mid);
}
if(p > mid){
Rs[now] = 0;
merge(Rs[las],Rs[now],p,mid + 1,r);
}
} inline ll find(int las,int now,int l,int r,int tl,int tr){
if(tl <= l && r <= tr)
return H[now] - H[las];
ll ans = 0;
if(tl <= mid)
ans += find(Ls[las],Ls[now],l,mid,tl,tr);
if(tr > mid)
ans += find(Rs[las],Rs[now],mid + 1,r,tl,tr);
return ans;
} //主席树 ll las = 0; inline void solve(ll now,ll l,ll r){
ll num = find(Head[dfn[now] - 1],Head[end[now]],1,n,l,r);
if(num == (r - l + 1)){
las = s[qlca(root,l,r)] - s[now];
std::cout<<las<<std::endl;
}else{
if(num != 0){
std::cout<<(las = 0)<<std::endl;
return ;
}
ll x = now;
for(int i = 29;i >= 0;--i){
int p = fa[x][i];
if(p != 0){
if(!(find(Head[dfn[p] - 1],Head[end[p]],1,n,l,r)))
x = fa[x][i];
}
}
if(fa[x][0] != 0 && !(find(Head[dfn[fa[x][0]] - 1],Head[end[fa[x][0]]],1,n,l,r)))
x = fa[x][0];
x = fa[x][0];
ll L1 = qlca(root,l,r);ll L2 = lca(now,L1);
if(L1 == L2)
las = s[now] - s[x];
else
las = s[now] - 2 * s[L2] + s[L1];
std::cout<<las<<std::endl;
return ;
}
} int main(){
scanf("%d%d",&n,&q);
for(int i = 1;i < n;++i){
ll x,y,w;
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
add(y,x,w);
}
dfs(1,0);
build(root);
for(int i = 1;i <= n;++i)
merge(Head[i - 1],Head[i],inv[i],1,n);
while(q -- ){
ll p,l,r;
scanf("%d%d%d",&p,&l,&r);
p ^= las;
l ^= las;
r ^= las;
solve(p,l,r);
}
}

『MdOI R1』Treequery的更多相关文章

  1. 洛谷 P6071 『MdOI R1』Treequery(LCA+线段树+主席树)

    题目链接 题意:给出一棵树,有边权,\(m\) 次询问,每次给出三个数 \(p,l,r\),求边集 \(\bigcap\limits_{i=l}^rE(p,i)\) 中所有边的权值和. 其中 \(E( ...

  2. P6072 『MdOI R1』Path

    考虑我们有这样操作. 我们只要维护两点在子树内和两点在子树外的异或和即可. 前者可以类似于线段树合并的trie树合并. 后者有两种做法: 一种是把dfn序翻倍:然后子树补变成了一个区间最大异或问题,可 ...

  3. 洛谷 P6072 -『MdOI R1』Path(回滚莫队+01-trie)

    题面传送门 又是 ix35 神仙出的题,先以 mol 为敬 %%% 首先预处理出根节点到每个点路径上权值的异或和 \(dis_i\),那么两点 \(a,b\) 路径上权值的异或和显然为 \(dis_a ...

  4. 洛谷 P6383 -『MdOI R2』Resurrection(DP)

    洛谷题面传送门 高速公路上正是补 blog 的时候,难道不是吗/doge,难不成逆在高速公路上写题/jy 首先形成的图显然是连通图并且有 \(n-1\) 条边.故形成的图是一棵树. 我们考虑什么样的树 ...

  5. LuoguP7337 『MdOI R4』Fun 题解

    Content 有 \(n\) 个人去打比赛.给出第 \(i\) 个人的交通方式 \(t_i\) 和颓废值 \(q_i\)(均以 \(0/1\) 表示).如果 \(t_i=1,q_i=1\) 的人数 ...

  6. 题解 P6745 『MdOI R3』Number

    前言 不知道是不是正解但是觉得挺好理解. 科学计数法 将一个数表示为\(a\times 10^x\) 的形式.其中\(a\leq10\),\(x\) 为整数. \(\sf Solution\) 其实这 ...

  7. 『TensorFlow Internals』笔记_源码结构

    零.资料集合 知乎专栏:Bob学步 知乎提问:如何高效的学习 TensorFlow 代码?. 大佬刘光聪(Github,简书) 开源书:TensorFlow Internals,强烈推荐(本博客参考书 ...

  8. 似魔鬼的 『 document.write 』

    在平时的工作中,楼主很少用 document.write 方法,一直觉得 document.write 是个危险的方法.楼主不用,并不代表别人不用,最近给维护的项目添了一点代码,更加深了我对 &quo ...

  9. 拾遗:『Linux Capability』

    『Linux Capability』 For the purpose of performing permission checks, traditional UNIX implementations ...

随机推荐

  1. 轻量级 Java 基础开发框架,Solon & Solon Cloud 1.5.48 发布

    Solon 已有120个生态扩展插件,此次更新主要为细节打磨: 增加 solon.serialization,做为序列化的基础插件 优化 所有Json序列化插件,使之可方便定制类型序列化 public ...

  2. 「软件测试实战教程系列(三)」弃繁就简,接口测试神器Postman|收藏版

    软件测试实战教程系列(三)弃繁就简,接口测试神器Postman|收藏版 Postman主要帮我们干了三件事: 1.把相关集合放到一个集合当中方便管理. 2.对指定接口发送请求. 3.断言 下面我们使用 ...

  3. .jar文件没有Java(TM) Platform SE binary打开方式解决办法

    下面是我个人在打开.jar文件时候的一些小问题: 明明已经配置好了环境变量.jar文件却没有 Java(TM) Platform SE binary 的打开方式, 网上查了资料点明是环境变量的问题,后 ...

  4. 改善深层神经网络-week1编程题(Regularization)

    Regularization Deep Learning models have so much flexibility and capacity that overfitting can be a ...

  5. CentOS 文件管理

    目录 目录管理 目录结构 切换目录 查看目录 创建目录 复制目录 剪切目录 删除目录 文件管理 查看文件 创建文件 复制文件 剪切文件 删除文件 创建链接 目录管理 目录也是一种文件. 蓝色目录,绿色 ...

  6. 【技术博客】Flutter—使用网络请求的页面搭建流程、State生命周期、一些组件的应用

    Flutter-使用网络请求的页面搭建流程.State生命周期.一些组件的应用 使用网络请求的页面搭建流程 ​ 在开发APP时,我们常常会遇到如下场景:进入一个页面后,要先进行网络调用,然后使用调用返 ...

  7. (二)、Docker 快速入门

    文档:https://docs.docker.com/install/linux/docker-ce/centos/ 中文文档:https://docs.docker-cn.com/engine/in ...

  8. time_formatter攻防世界学习

    time_formatter 前言:这题说实话分析量蛮大的,首先是程序内壁比较绕,而且调用了之前许多没有见到的函数---如snprintf_che,以及strsup(好像打错了),getegid(), ...

  9. Noip模拟57 2021.9.20

    规律总结:联考必爆炸 T1 2A 没$A$掉的大水题,但是是真的不知道$000$前面的$00$也算先导$0$,以后要长记性,这种东西不能再错了 再打三遍: $000$前面的$00$也算先导$0$ $0 ...

  10. Python里字符串Format时的一个易错“点”

    这是一篇很小的笔记,原因是我做学习通的时候见到了这个题: 当时看了一会儿发现没有符合自己想法的答案,然后就脑袋一热选了C,结果当然是错了... 看了一眼这个format的字符串对象,发现有个 {:7. ...