P9853 [入门赛 #17] 方程求解 题解
Source & Knowledge
2023 年 11 月语言月赛,由洛谷网校入门计划/基础计划提供。
考察字符串的运用和桶的思想。
文字题解
题目中给出了若干个一元一次方程。我们如何求解方程呢?
对于一个方程
再两边同时除以
解方程的任务并不算太困难。困难的是,我们如何从给定的算式中提取出
-
自己编写一个读入,过滤掉其中的非数字字符,只保留数字字符,还原出原始的数字。实际上如果你接触过“快速读入”这一技巧,会发现这其实是一样的步骤。
-
使用 scanf 进行字符串的格式化。具体而言,我们可以在 scanf 过程中指定读入的格式,让每一个
%d都对应到具体位置上的数字,赋值给具体的变量。也就是:scanf("%dx%d=%d",&a,&b,&c);,它就会根据x和=这两个字符进行切分,将三个数划分给变量a,b,c 。
下一个任务是,我们如何回答,在
对于入门赛版本,其数据范围较大:
数据保证,
1\leq n,Q\leq 2\times 10^5 ,方程中a_i,b_i,c_i 满足1 \leq |a_i|,|b_i|,|c_i| \leq 10^9 ,每一组方程的解x_i 必定为正整数。询问时的L,R 满足1\leq L\leq R\leq 2\times 10^9 。
如果我们使用语言月赛版本中的做法,无论是空间上(需要一个
如果
在排序后,实际上我们要求出的就是,第一个大于等于 lower_bound 函数与 upper_bound 函数。这两个函数均使用了二分查找的原理,可以在有序的数组中寻找要求的元素。其中:
lower_bound函数返回大于或等于给定值的第一个元素的迭代器(或者可以理解为下标地址)。upper_bound函数返回大于给定值的第一个元素的迭代器(或者可以理解为下标地址)。
根据这些函数,我们可以编写出对应的代码了。该算法的时间复杂度为
详细的代码请参考视频题解。