洛谷 P2633 Count on a tree

2023-05-16

题目描述

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

输入输出格式

输入格式:

 

第一行两个整数N,M。

第二行有N个整数,其中第i个整数表示点i的权值。

后面N-1行每行两个整数(x,y),表示点x到点y有一条边。

最后M行每行两个整数(u,v,k),表示一组询问。

 

输出格式:

 

M行,表示每个询问的答案。

 

输入输出样例

输入样例#1:

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2  
输出样例#1:

2
8
9
105
7  

说明

HINT:

N,M<=100000

暴力自重。。。

来源:bzoj2588 Spoj10628.

本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。

思路:主席树+LCA

 

以点的dfs序为下标,以点权为区间建立主席树

 

以前做过的主席树在序列上,所以是以前一个节点的线段树为基准建立的

 

这里在树上,所以可以考虑以根为基准建立线段树

 

u,v间增加的点数=cnt[u]+cnt[v]-cnt[LCA(u,v)]-cnt[father[LCA(u,v)]]

 


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100001
using namespace std;
int n,m,tot,cnt,num,lastans;
int a[MAXN],ha[MAXN],root[MAXN];
int to[MAXN*2],net[MAXN*2],head[MAXN*2];
int top[MAXN],dad[MAXN],deep[MAXN],size[MAXN];
struct nond{
    int l,r,cnt;
}tree[MAXN*20];
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
    to[++tot]=u;net[tot]=head[v];head[v]=tot;
}
void insert(int pre,int &now,int l,int r,int k){
    tree[now=++num].cnt=tree[pre].cnt+1;
    if(l==r)    return ;
    int mid=(l+r)/2;
    if(k<=mid){
        tree[now].r=tree[pre].r;
        insert(tree[pre].l,tree[now].l,l,mid,k);
    }
    else{
        tree[now].l=tree[pre].l;
        insert(tree[pre].r,tree[now].r,mid+1,r,k);
    }
}
int query(int x,int y,int LCA,int fa_LCA,int l,int r,int k){
    if(l==r)    return a[l];
    int mid=(l+r)/2;
    int tmp=tree[tree[x].l].cnt+tree[tree[y].l].cnt-tree[tree[LCA].l].cnt-tree[tree[fa_LCA].l].cnt;
    if(k<=tmp)    query(tree[x].l,tree[y].l,tree[LCA].l,tree[fa_LCA].l,l,mid,k);
    else    query(tree[x].r,tree[y].r,tree[LCA].r,tree[fa_LCA].r,mid+1,r,k-tmp);
}
void dfs(int now){
    size[now]=1;
    insert(root[dad[now]],root[now],1,cnt,ha[now]);
    deep[now]=deep[dad[now]]+1;
    for(int i=head[now];i;i=net[i])
        if(dad[now]!=to[i]){
            dad[to[i]]=now;
            dfs(to[i]);
            size[now]+=size[to[i]];
        }
}
void dfs1(int x){
    int t=0;
    if(top[x]==0)    top[x]=x;
    for(int i=head[x];i;i=net[i])
        if(dad[x]!=to[i]&&size[to[i]]>size[t])
            t=to[i];
    if(t){
        top[t]=top[x];
        dfs1(t);
    }
    for(int i=head[x];i;i=net[i])
        if(dad[x]!=to[i]&&t!=to[i])
            dfs1(to[i]);
}
int lca(int x,int y){
    for(;top[x]!=top[y];){
        if(deep[top[x]]<deep[top[y]])
            swap(x,y);
        x=dad[top[x]];
    }
    if(deep[x]>deep[y])
        swap(x,y);
    return x;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        ha[i]=a[i];
    }
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    sort(a+1,a+1+n);
    cnt=unique(a+1,a+1+n)-(a+1);
    for(int i=1;i<=n;i++)
        ha[i]=lower_bound(a+1,a+1+cnt,ha[i])-a;
    dfs(1);
    dfs1(1);
    for(int i=1;i<=m;i++){
        int u,v,k;
        scanf("%d%d%d",&u,&v,&k);
        u^=lastans;
        int LCA=lca(u,v);
        lastans=query(root[u],root[v],root[LCA],root[dad[LCA]],1,cnt,k);
        if(i!=m)    cout<<lastans<<endl;
        else cout<<lastans;
    }
}  

 

转载于:https://www.cnblogs.com/cangT-Tlan/p/7603653.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

洛谷 P2633 Count on a tree 的相关文章

  • Visual Studio代码侧边栏垂直引导线(自定义侧边栏)

    有人知道 Visual Studio 代码的扩展可以像 netbeans 一样在侧边栏 用于文件和文件夹 上显示垂直指南吗 或者vscode中有一些设置吗 Netbeans 快照 https i stack imgur com CFJsw
  • Python-如何获取文本文件中的行数[重复]

    这个问题在这里已经有答案了 我想知道是否可以在不使用命令的情况下知道有多少行包含我的文件文本 with open test txt as f text f readlines size len text 我的文件非常大 所以很难使用这种方法
  • 计算 Java 集合中出现次数的优雅方法

    给定一个可能有重复项的对象集合 我希望最终得到每个对象的出现次数 我通过初始化一个空的来做到这一点Map 然后迭代Collection并将对象映射到其计数 每次映射已包含该对象时增加计数 public Map
  • 如何递归探索Python嵌套字典? [复制]

    这个问题在这里已经有答案了 我很好奇是否有一种方法可以在 python 中递归地探索嵌套字典 我的意思是 假设我们有一个如下示例 d a b c 1 2 3 获取最里面字典的内容需要什么代码 c 1 2 3 遍历a and b 在这种情况下
  • 二叉搜索树是平衡的吗?

    这已经讨论过了here https stackoverflow com questions 742844 how to determine if binary tree is balanced 但我在下面有一个实现 线程中从未讨论过 pub
  • 迭代多级提升树

    我的树看起来像这样 Library L ID 1 Book B ID 1 Title Moby Dick Book B ID 2 Title Jurassic Park Library L ID 2 Book B ID 1 Title Ve
  • 寻找成熟的 M-Tree 实现 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个成熟的 java M Tree 实现 甚至任何 M Tree 实现 除了我找到的唯一实现 http en wikipedia
  • MySQL - 按 count() 和 GROUP BY 排名

    我有我的 mysql 表posts 我的论坛的所有帖子都存储在其中 就像这样 id uid thread post title text time int int varchar int varchar text int 现在我想显示用户个
  • 将具有相同 ID 的多行(具有一些非字符串值)合并到 pandas 中的一个分隔行中

    我有一个这样的数据集 ID Name 1 a 1 b 1 2 1 3 2 er 2 get 2 better 3 123 3 cold 3 warm 3 sweet 3 heat 我想将这些数据分组在一起 以便使用分隔符将具有相同 id 的
  • 按“计数(列不为空)”排序

    我正在寻找一种方法 通过值不为空的列的计数来对 MySQL 结果进行排序 所以 id 1 1 0 1 1 4 id 0 1 1 1 0 3 id 0 0 0 1 1 2 id 1 0 0 0 0 1 在上面的例子中 我忽略了 ID 列 但实
  • 检查 PHP 数组中特定值的出现次数 [重复]

    这个问题在这里已经有答案了 我有一个名为 uid 的数组 如何检查值 12 在我的 uid 数组中出现了多少次 几种方法 cnt count array filter uid function a return a 12 or tmp ar
  • pandas 数据框中的 count 和 countif

    我有一个 DF 如下所示 trainee course completed days overdue Ava ABC Yes 0 Bob ABC Yes 1 Charlie DEF No 10 David DEF Yes 0 Emily D
  • 将 python NLTK 解析树保存到图像文件[重复]

    这个问题在这里已经有答案了 这可能会复制这个 stackoverflowquestion https stackoverflow com questions 23429117 saving nltk drawn parse tree to
  • CakePHP GROUP 和 COUNT 个项目在列表中返回

    我知道这里有一些类似的问题 但它们都是关于使用时的 Model gt find all 但这不是我正在做的 我正在做的 Model gt find list 这就是工作与不工作之间的区别 给定一组产品 我想找到该组中的所有品牌以及每个品牌的
  • 如何按层次结构对文件路径名进行排序?

    我想按层次结构对文件名进行排序 假设我有以下文件夹列表 D Movies Hollywood Comedy adultcomedy D Movies Hollywood Comedy horrorcomedy D Movies Hollyw
  • 非二叉树的中序树遍历

    对于比二叉树更宽的树 术语 中序遍历 是否有明确定义的含义 或者 前 和 后 顺序是唯一有意义的 DFS 类型吗 我的意思是与n每个节点 gt 2 个子节点 我猜是为了n这甚至可能意味着之后要转到 根 n 2孩子们 但这曾经这样使用过吗 那
  • 在关系数据库中存储树结构的已知方法有哪些? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 XSLT 从平面 XML 列表构建树?

    我使用极简 MVC 框架 其中PHP控制器手上的DOM模型 to the XSLT 视图 c f okapi http okapi liip ch 为了构建导航树 我在 MYSQL 中使用了嵌套集 这样 我最终得到一个如下所示的模型 XML
  • 对带有空白 NVARCHAR 或 NULL 检查的 VARCHAR 索引进行 Count(*) 会导致返回的行数加倍

    我有一张桌子 上面有VARCHAR列及其上的索引 每当一个SELECT COUNT 是在这张表上完成的 该表检查了COLUMN N OR COLUMN IS NULL它返回双倍的行数 SELECT 与相同的where子句将返回正确的记录数
  • 使用 Java 进行树可视化 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个库来生成图形或树 例如组织图表 该库应该能够从该图中生成纯图像 有谁知道一个好的 希望开源

随机推荐

  • 算法导论学习笔记02——最大子数组问题

    最大子数组问题 xff1a 输入一个数组A xff0c 在数组A的众多非空连续子数组中 xff0c 找到和最大的一个 目录 暴力求解方法 分治思想求解 分治思想C代码 测试脚本 暴力求解方法 对一个长度为A的数组 xff0c 可以存在个非空
  • Linux中各文件占用的Cache统计

    统计Linux中各个文件占用cache的情况 xff0c 使用工具fincore 可以从GitHub上获取到源码 xff1a https github com david415 linux ftools git 下载后 xff0c conf
  • 算法导论学习笔记05——求一个数列中第N大的数字

    本篇文章根据快速排序的分治思想在排序的情况下求解一个数列中第N大的数字 关于快速排序的原理和实现算法导论学习笔记04 快速排序 快速排序中介绍了一种PARTITION 函数 xff0c 它将原数组A r 使用一个主元x xff08 A 的某
  • 求最大数和最小数的最大公约数

    从键盘输入10个正整数 xff0c 求出最大数 xff0c 最小数 xff0c 以及他们的最大公约数 要求用数组实现 程序运行结果示例1 xff1a Input 10 numbers 15 23 56 87 94 105 78 19 22
  • 文件名排序(自然序)

    文件名就是一个字符串 xff0c 在对两个文件名进行比较时 xff0c 当文件名中有数字时 xff0c 仅仅按照字典序逐个字符的比较会出现如下不合理的情况 xff1a 文件 xff1a 10 a 11 a 100 a 排序的结果是10 a
  • 算法导论学习笔记06——二叉搜索树

    二叉搜索树以二叉树的形式组织数据 xff0c 每个节点除了记录key值和卫星数据 xff08 非key值的数据 xff09 外 xff0c 还需要三个指针 xff1a left xff08 指向左孩子 xff09 right xff08 指
  • Ubuntu 编译安装 php7.4

    安装依赖 sudo apt update sudo apt install gcc y amp amp sudo apt install make y amp amp sudo apt install openssl y amp amp s
  • WSL2 启用systemd

    WSL2 启用systemd 项目 wsl distrod 安装方法 一 1 确保默认的WSL本版为2 wsl set default version 2 2 下载并解压缩 distrod wsl launcher xff0c 解压提取ex
  • WSL2安装k8s

    WSL2启用systemd 参考这个方法 xff1a https blog csdn net hiqiming article details 125111806 spm 61 1001 2014 3001 5501 关闭swap 在当前W
  • VMware中 CentOS7网络配置

    1 检测网络是否可用 gt Ping 114 114 114 114 注意 xff1a 不要通过ping www baidu com等网站来进行测试 2 VMWare安装后的5个服务 xff08 1 xff09 Authorization
  • 数据结构学习笔记——栈

    栈 栈栈的顺序存储结构及其基本运算实现顺序栈4要素基于顺序栈的基本运算共享栈共享栈的4要素 栈的链式存储结构及其基本运算实现链栈4要素基于链栈的基本运算 栈 栈的顺序存储结构及其基本运算实现 顺序栈 4要素 基于顺序栈的基本运算 共享栈 共
  • BUG List

    BUG List 人类从历史中学到的唯一教训 xff0c 就是人类无法从历史中学到任何教训 黑格尔 Linux 常见 gedit bashrc bashrc是home目录下的一个shell文件 xff0c 用于储存用户的个性化设置 在bas
  • 为什么区间要写成左闭右开?

  • SUSE服务器上安装R语言

    参考 xff1a http blog sina com cn s blog 6caea8bf0100zfbu html 1 解压文件 xff1a tar zvxf R 2 13 2 tar gz 2 进入R源文件目录 xff1a cd R
  • n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始(18)

    第18题 xff1a 题目 xff1a n个数字 xff08 0 1 n 1 xff09 形成一个圆圈 xff0c 从数字0开始 xff0c 每次从这个圆圈中删除第m个数字 xff08 第一个为当前数字本身 xff0c 第二个为当前数字的下
  • 最大公约数算法——欧几里德算法

    欧几里德算法又称辗转相除法 xff0c 用于计算两个整数m和n 0 m lt n 的最大公约数 xff0c 记为gcd m n 其计算过程是重复应用下列等式 xff0c 直到n mod m 61 0 gcd m n 61 gcd n mod
  • 安装显卡驱动时遇到The CC version check failed问题解决方法

    在Ubuntu上安装显卡驱动时报以下错误 xff1a The CC version check failed The kernel was built with gcc version 5 4 0 20160609 Ubuntu 5 4 0
  • 几款免费好用的OCR工具

    相信经常看书的同学会有想把书里面的图片转成文字的需求 xff0c 搜集了下最近尝试的在Mac能用的OCR工具 xff0c 汇总出来 1 Microsoft Onenote 实在是找不到那个右键 gt copy as text 2 Googl
  • 洛谷 P1591 阶乘数码

    P1591 阶乘数码 题目描述 求n 中某个数码出现的次数 输入输出格式 输入格式 xff1a 第一行为t 10 xff0c 表示数据组数 接下来t行 xff0c 每行一个正整数n 1000 和数码a 输出格式 xff1a 对于每组数据 x
  • 洛谷 P2633 Count on a tree

    P2633 Count on a tree 题目描述 给定一棵N个节点的树 xff0c 每个点有一个权值 xff0c 对于M个询问 u v k xff0c 你需要回答u xor lastans和v这两个节点间第K小的点权 其中lastans