洛谷P8972 『GROI-R1』 一切都已过去(树上前缀和+运算符重载)

『GROI-R1』 一切都已过去

题目背景

悦关上窗,拉上帘布。

果然还是想不起来啊。

隐约记得曾和什么人一起做过这样的事。

仰面躺下,手执一只木笺。

「究竟如何,才能拥有“过去”啊……」

她闭上双眼。

「6 岁前的记忆……究竟如何才能寻回?」

题目描述

悦正在寻找她的记忆。忽然,她来到了有 n n n 个节点的一棵树上。树上每一条边都有各自边权,每一个点都有各自的点权。

「把经历都聚拢起来,能完整地复原吗……」

悦从树上的一个点,慢慢地走到了另一个点,可是她什么也没找到。但是,她不知道,玘一直在远处望着她走过的道路。

玘发现,悦全程没有走回头路。他想把悦走过的每一条边的边权乘起来,可惜他发现他遇到了一个这一生未曾见到过的数字。

「为什么会这样呢?」

玘想到悦是突然出现在树上的,最初的点一定有蹊跷!他把最初那个点的点权乘上……

突然,一束彼岸花的红光亮起!世界重新安静了下来。

悦看到了玘留下的字样,可惜她不能从中看出任何过去的记忆。现在,你要帮她判断:把经历都聚拢起来,能完整地复原过去吗?我们称悦的一条路径能“复原过去”,当且仅当玘留下的乘积是一个整数

形式化题面

给定一棵 n n n 个节点的树和 q q q 次询问。每次询问给出两个整数 x , y x,y x,y,表示询问树上以 x x x y y y 为端点的简单路径上边权乘积与点 x x x 的点权相乘是否为整数。

输入格式

第一行两个正整数 n n n q q q,表示树上有 n n n 个节点编号为 1 ∼ n 1\sim n 1n,悦在树上走了 q q q 条路径。

接下来一行 n n n 个非负整数表示每个点的点权 a i a_i ai

接下来 n − 1 n-1 n1 行每行两个正整数 u , v u,v u,v 和一个非负实数 w w w 表示 u , v u,v u,v 间有一条边权为 w w w 的边。

接下来 q q q 行,每行两个正整数 x , y x,y x,y,表示悦从点 x x x 开始走到了点 y y y

输出格式

对于悦的每一次询问,你需要输出一行一个字符串。如果悦能够成功复原她的过去,请输出 Yes,否则请输出 No

样例 #1

样例输入 #1

5 3
1 2 3 4 5
1 2 0.1
2 3 0.20
3 4 0.5
2 5 0.99
1 5
1 4
4 3

样例输出 #1

No
No
Yes

提示

样例解释

根据输入可以得到下图:

对于第一个询问 ( 1 , 5 ) (1,5) (1,5) 可以发现悦经过的边的边权分别是 0.1 0.1 0.1 0.99 0.99 0.99,她出发的 1 1 1 号点的点权为 1 1 1 1 × 0.1 × 0.99 = 0.099 1\times0.1\times0.99=0.099 1×0.1×0.99=0.099 不是整数。所以输出 No

对于后面两次询问同理。

数据范围

本题采用捆绑测试。

子任务编号数据范围特殊性质分值
Subtask1 \text{Subtask1} Subtask1 n , q ≤ 3 × 1 0 3 n,q\le3\times 10^3 n,q3×103 15 15 15
Subtask2 \text{Subtask2} Subtask2 n ≤ 500 n\le500 n500 q ≤ 1 0 5 q\le10^5 q105 10 10 10
Subtask3 \text{Subtask3} Subtask3 n , q ≤ 1 0 5 n,q\le10^5 n,q105 BE \text{BE} BE 10 10 10
Subtask4 \text{Subtask4} Subtask4 n , q ≤ 1 0 5 n,q\le10^5 n,q105 A \text{A} A 5 5 5
Subtask5 \text{Subtask5} Subtask5 n , q ≤ 1 0 5 n,q\le10^5 n,q105 B \text{B} B 10 10 10
Subtask6 \text{Subtask6} Subtask6 n , q ≤ 1 0 5 n,q\le10^5 n,q105 C \text{C} C 5 5 5
Subtask7 \text{Subtask7} Subtask7 n , q ≤ 1 0 5 n,q\le10^5 n,q105 D \text{D} D 10 10 10
Subtask8 \text{Subtask8} Subtask8 n , q ≤ 2 × 1 0 5 n,q\le2×10^5 n,q2×105 35 35 35

特殊性质 A \text{A} A:保证树退化成一条链。

特殊性质 B \text{B} B:保证树随机生成(即对于每一个节点随机选择它的父亲节点)。

特殊性质 C \text{C} C:保证 w ∈ { 0.1 , 0.3 , 0.5 , 0.7 , 0.9 } w\in\{0.1,0.3,0.5,0.7,0.9\} w{0.1,0.3,0.5,0.7,0.9}

特殊性质 D \text{D} D:保证 w ∈ { 0.1 , 0.2 , 0.3 , 0.4 , 0.6 , 0.7 , 0.8 , 0.9 } w\in\{0.1,0.2,0.3,0.4,0.6,0.7,0.8,0.9\} w{0.1,0.2,0.3,0.4,0.6,0.7,0.8,0.9}

特殊性质 E \text{E} E:保证 w ≤ 2 w\le2 w2 w w w 小数位数不超过 1 1 1 位。

对于 100 % 100\% 100% 的数据满足 1 ≤ n , q ≤ 2 × 1 0 5 1\le n,q\le2\times10^5 1n,q2×105 0 ≤ a i ≤ 1 0 9 0\le a_i\le10^9 0ai109 0 ≤ w ≤ 1 0 4 0\le w\le10^4 0w104 1 ≤ u , v , x , y ≤ n 1\le u,v,x,y\le n 1u,v,x,yn x ≠ y x\ne y x=y w w w 小数位数不超过 4 4 4 位。

涉及知识:树上前缀和(LCA),运算符重载。

思路:对于树上两节点间距离或者权值和之类的问题很容易想到树上前缀和的思路,但是按照表面意思进行前缀和之间的乘法的话精度完全不够所以需要转换一下思维,为了让一个小数转换成整数,我们可以枚举一下看看。
得到的可以完成整数转换的其实只有一类:

//0.5*2 -> 0.1 * 5 * 2  --
//0.2*5	-> 0.1 * 5 * 2  ---> 0.1 * 10
//0.4*2.5 -> 0.01 * 5^2 * 2^2  ---> 0.01 * 10^2

因此,只需要统计一下2和5的次幂数以及所有小数点后位数之和,那么2和5组成的是的次幂数即 n u m 10 = m i n ( n u m 2 , n u m 5 ) num_{10} = min(num_2,num_5) num10=min(num2,num5) 。并比较其与小数点后位数之和的大小即得答案。
其中有两个坑点:
如果你的代码TLE了,可能是因为你没有考虑点权为0的情况。
如果你的代码WA了,可能是以为你没有考虑边权出现0的情况。
因此我们只需要特判一下以上两种情况就差不多解决这个问题了。

#include <bits/stdc++.h>
using namespace std;#define all(x) x.begin(), x.end()
#define bit1(x) __builtin_popcount(x)
#define Pqueue priority_queue
#define lc p << 1
#define rc p << 1 | 1
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#define fi first
#define se secondtypedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<ll, ll> PII;const ll mod = 1000000007;
const ll N = 1e6 + 10;
const ld eps = 1e-9;
const ll inf = 1e18;
const ll P = 131;
const ll dir[8][2] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1};struct node
{int a, b, c;
} g[N];//定义一个结构体a,b,c依次对应小数点后位数、2的次幂数、5的次幂数
//即由1到第i个节点的树上前缀和
node operator*(node a, int b)
{return node({a.a * b, a.b * b, a.c * b});
}//重载运算符 *
node operator+(node a, node b)
{return node({a.a + b.a, a.b + b.b, a.c + b.c});
}//重载运算符 +
node operator-(node a, node b)
{return node({a.a - b.a, a.b - b.b, a.c - b.c});
}//重载运算符 -
ostream &operator<<(ostream &out, node a)
{out << a.a << " " << a.b << " " << a.c << "\n";return out;
}//重载运算符 << (用于Debug)
node check(double x)
{node tmp({0, 0, 0});if (x == 0)return tmp;while (x != (ll)x){x *= 10;tmp.a++;}//取小数点后位数ll t = x;while (t % 2 == 0){t /= 2;tmp.b++;}//取2的次幂数while (t % 5 == 0){t /= 5;tmp.c++;}//取5的次幂数return tmp;
}//返回一个实数x包含的node信息int fa[N][21];//父节点数组i的第2^j位父亲
int dep[N];	//深度数组
int Log2[N + 10];//预处理Log2数组
int zero[N];	//0的树上前缀和数组,由1到第i个节点路径上0的个数
int n, m, u, v;
double w;
vector<pair<int, double>> G[N];	//邻接表存图void Dfs(int u, int f)		//DFS求LCA并构建树上前缀和
{dep[u] = dep[f] + 1;	//求深度fa[u][0] = f;			//u的第一个父亲是ffor (int i = 1; i <= Log2[dep[u]]; i++)fa[u][i] = fa[fa[u][i - 1]][i - 1];	//u的第2^i个父亲是 (u的第2^{i-1}个父亲) 的第 2^{i-1} 个父亲for (auto [v, w] : G[u])	//遍历子节点{if (v == f)continue;zero[v] = zero[u] + (w==0);	//统计0的个数g[v] = g[u] + check(w);		//统计其他树上前缀和Dfs(v, u);}
}
int Lca(int a, int b)				//倍增法求LCA
{if (dep[a] > dep[b])swap(a, b);while (dep[a] != dep[b])b = fa[b][Log2[dep[b] - dep[a]]];if (a == b)return a;for (int i = Log2[dep[a]]; i >= 0; i--)if (fa[a][i] != fa[b][i])a = fa[a][i], b = fa[b][i];return fa[a][0];
}void solve()
{// node a({1, 2, 3}), b({3, 2, 1});// cout << a * 2;// cout << a + b;// cout << a - b;cin >> n >> m;vector<int> val(n + 10);for (int i = 1; i <= n; i++)cin >> val[i];for (int i = 1; i < n; i++){cin >> u >> v >> w;G[u].push_back({v, w});G[v].push_back({u, w});}Dfs(1, 0);// for (int i = 1; i <= n; i++)//     cout << g[i];for (int i = 1; i <= m; i++){cin >> u >> v;node tmp = g[u] + g[v] - g[Lca(u, v)] * 2 + check(val[u]);//由 u 到 v 路径上的树上前缀和 + 点权中的信息// cout << check(cal[u]) << tmp;int z = zero[u] + zero[v] - zero[Lca(u, v)] * 2;	//0的树上前缀和if (!val[u] || z > 0 || min(tmp.b, tmp.c) >= tmp.a)//特判两个坑点cout << "Yes\n";elsecout << "No\n";}
}int main()
{Log2[0] = -1;for (int i = 1; i <= N; i++)Log2[i] = Log2[i / 2] + 1;//预处理Log2数组IOS int T = 1;// cin>>T;while (T--)solve();return 0;
}/*
oxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxox
x                                                                                      o
o       _/_/_/_/                                                              _/       x
x      _/                                                                              o
o     _/_/_/_/ _/  _/_/   _/_/   _/_/_/ _/_/   _/_/_/     _/_/    _/_/_/    _/ _/   _/ x
x    _/       _/_/     _/    _/ _/   _/   _/  _/    _/ _/    _/  _/    _/  _/   _/ _/  o
o   _/       _/       _/    _/ _/   _/   _/  _/    _/ _/    _/  _/    _/  _/    _/_/   x
x  _/       _/         _/_/   _/   _/   _/  _/_/_/     _/_/ _/ _/    _/  _/      _/    o
o                                          _/                           _/      _/     x
x                                         _/                        _/_/       _/      o
o                                                                                      x
xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2871007.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

十、MySQL主从架构配置

一、资源配置 主库&#xff1a;192.168.134.132 从库&#xff1a;192.168.134.133 从库&#xff1a;192.168.134.134 二、主从同步基本原理&#xff1a; master用户写入数据&#xff0c;会生成event记录到binary log中&#xff0c;slave会从master读取binlog来进行数据同步…

<商务世界>《第12课 发票种类和增值税专用发票的税率》

1 增值税发票类型 分为增值税发票和增值税专用发票&#xff0c;都是税务部门为了管理增值税而设立的重要工具&#xff0c;但它们在使用范围、功能以及具体的格式等方面存在明显的区别。 1.1 增值税发票 是一种广泛使用的税务凭证&#xff0c;它涵盖了多种类型的发票&#xf…

VPTTA:为每张医疗图像生成特定的“提示”,解决跨不同设备和条件的医疗图像分割的准确性和适应性

VPTTA&#xff1a;为每张医疗图像生成特定的“提示”&#xff0c;解决跨不同设备和条件的医疗图像分割的准确性和适应性 提出背景VPTTA 方法VPTTA 步骤 提出背景 论文&#xff1a;https://arxiv.org/pdf/2311.18363.pdf 代码&#xff1a;https://github.com/Chen-Ziyang/VPTT…

STM32输入捕获模式测频率

STM32频率的测量&#xff1a;高频适合使用的方法是测频法&#xff0c;低频适合使用的是测周法&#xff0c;&#xff08;其中使用测频法测量频率比较稳定&#xff0c;使用测周法测量频率的方式没有这么稳定&#xff0c;因为测周法只会通过一次的测量就能得出结果所以测试出来的频…

kubernetes-有状态和无状态服务

kubernetes-有状态和无状态服务 kubernetes-有状态和无状态服务1.有状态的应用1.1、理解1.2、特点 2、无状态应用2.1、理解2.2、特点 3、玩一下3.1、启动一个nginx无状态的业务3.2、启动一个nginx有状态的业务 4、无头服务4.1、无头服务的特点&#xff1a;4.2、无头服务的用途&…

verilog 从入门到看得懂---verilog 的基本语法数据和运算

笔者之前主要是使用c语言和matab 进行编程&#xff0c;从2024年年初开始接触verilog&#xff0c;通过了一周的学习&#xff0c;基本上对verilog 的语法有了基本认知。总统来说&#xff0c;verilog 的语法还是很简单的&#xff0c;主要难点是verilog是并行运行&#xff0c;并且强…

2024/3/15 记录简版抖音部署遇到的问题

1、Centos连不上网 参考这一篇&#xff1a;虚拟机 CentOS 有线连接图标直接消失&#xff0c;网络连接不上&#xff0c;网络连接失败的解决方案&#xff08;亲测有效&#xff09;_centos网络图标不见了-CSDN博客 2、SQLyog连接不到docker中的mysql 原因是对密码有加密过程 &a…

面向对象编程第三式: 多态 (Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

浅谈C/C++的常量const、指针和引用问题

今天我们来探讨C/C中const、指针和引用的相关问题。这些概念是编程中的重要组成部分&#xff0c;它们的正确使用对于代码的可读性和可维护性至关重要。通过深入了解const的不可变性、指针的灵活性以及引用的简洁性&#xff0c;我们能够更好地掌握编程的精髓&#xff0c;并写出更…

顺序表操作

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;既然选择了远方&#xff0c;当不负青春…

Python语法糖

N u m P y NumPy NumPy的 n d i t e r nditer nditer nditer 是 NumPy 提供的一种多维迭代器&#xff0c;用于对多维数组进行迭代操作。它可以替代传统的嵌套循环&#xff0c;在处理多维数组时更加方便和高效。 迭代器可以按照不同的顺序遍历数组的元素&#xff0c;也可以控制…

(含链接)2024年NVIDIA GPU技术大会开发者合集(专为开发者挑选的合集)

2024年NVIDIA GPU技术大会开发者合集 我专门为开发者整理了NVIDIA GPU技术大会上专注技术的内容合集, 希望可以帮助开发者朋友们快速了解NVIDIA的最新技术. 注意:在电脑端打开更友好, 可以直接进入每一项的网页 文章目录 2024年NVIDIA GPU技术大会开发者合集如何登录和预约会…

【论文笔记合集】ARIMA 非平稳过程通过差分转化为平稳过程

本文作者&#xff1a; slience_me 文章目录 ARIMA 非平稳过程通过差分转化为平稳过程文章原文具体解释详解参照 ARIMA 非平稳过程通过差分转化为平稳过程 文章原文 Many time series forecasting methods start from the classic tools [38, 10]. ARIMA [7, 6] tackles the fo…

虚拟内存相关知识汇总(程序重定位)

前置知识&#xff1a; Windows的内存可以被分为两个层面&#xff1a;物理内存和虚拟内存。其中&#xff0c;物理内存非常复杂&#xff0c;需要进入到Windows内核级别ring0才能看到。通常在用户模式下&#xff0c;用调试器看到的内存地址都是虚拟地址。 1.虚拟内存的定义 虚拟…

Java实现知乎热点小时榜爬虫

1.效果演示 1.1 热点问题列表 启动程序后&#xff0c;自动展示热点问题&#xff0c;并等待终端输入 1.2 根据序号选择想看的热点问题 输入问题序号&#xff0c;展示回答内容 1.3 退出 输入q即可退出程序 2.源码 2.1 pom.xml <?xml version"1.0" enco…

腾讯云怎么申请免费服务器?2024免费云主机申请教程

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

2024年腾讯云免费服务器申请教程,个人和企业均可领取

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

大数据数据分析-scala、IDEA、jdk之间的搭配关系

Scala主要是一门面向对象编程语言和函数式编程语言。 一、大数据框架&#xff08;处理海量/流式数据&#xff09; - ---以HADOOP 2. x为系列的大数据生态系统处理框架 离线数据分析&#xff0c;分析的数据为N1天数据 -----MapReduce 并行计算框架&#xff0c;分而治之…

Java数据结构二叉树练习

1.检查两棵二叉树是否都是相同的练习 我要求时间复杂度为1&#xff0c;所以我们不用前序中序后序是否都一样来进行判断 如何判断二叉树是否都是相同的子问题方式 先判断根节点是否相同 再判断左子树和右子树是否都是相同的 先用代码判断不相同的情况&#xff0c;都相同的化…

多线程JUC 第2季 wait和notify唤醒机制

一 wait和notify的区别与相同 1.1 wait和notify的作用 1) 使用wait()、notify()和notifyAII()时需要先对调用对象加锁。否则直接调用的话会抛出 IllegalMonitorStateExceptiona。 2) 调用wait()方法后&#xff0c;线程状态。由RUNNING变为WAITING&#xff0c;并将当前线程放置…