题目链接:信息学奥赛比赛系统 | 强制在线带修区间LCM (qduoj.com)
先说点题外话,这个题目困扰了我一天多,刚ac,真的是太爽了,感觉从这里面学到的东西挺多的,所以就来分享一下。
题目的意思很明确,就是支持两种操作,一种是单点更改,另一个是区间最小公倍数的查询。看到这道题的第一想法就是直接上线段树模板再加一个lcm函数即可,但是我没想到的是在求最小公倍数的过程中会溢出,我们不可能对其取模完再求最小公倍数,这样结果显然是有问题的。提到这,我先来说一下a,b与他们的最小公倍数和最大公约数之间的关系吧!
先利用质因数分解定理得到:
a = ( p1^x1 ) * ( p2^x2 ) * ( p3^x3 ) * …… * ( pn^xn )
b = ( p1^y1 ) * ( p2^y2 ) * ( p3^y3 ) * …… * ( pn^yn )
则 lcm( a , b ) = ( p1^max (x1 , y1) ) * ( p2^max (x2 , y2) ) * ( p3^ max (x3 , y3) * …… * pn^max (xn , yn) )
而gcd( a, b ) = ( p1^min (x1 , y1) ) * ( p2^min (x2 , y2) ) * ( p3^ min (x3 , y3) * …… * pn^min (xn , yn) )
同理这个关系适用于多个数之间,所以为了求区间的最小公倍数,就需要维护区间中每个质因子出现的最大次数。
下面我来说一下如何维护区间中每个质因子出现的最大次数,我们观察数据范围发现数值的大小是小于100的,也就是说2这个素因子最多出现6次,用3位01串就可以表示,3这个素因子最多出现4次,5和7这两个素因子最多出现2次,这三个素因子用2位01串就可以表示,11,13,17……97这些小于100的素因子最多出现1次,用1个01串就可以表示,表示这25个素因子总共需要30位数,完全可以用一个int类型的整数进行压缩,下面先附上压缩函数的代码:
int change(int x)//把x的质因子压缩成一个数
{
int ans=0;

博客分享了一种使用压缩技术和线段树解决在线区间最小公倍数查询的问题,详细解释了质因数分解定理、如何压缩和解压质因子次数、线段树的pushup操作以及两种不同的实现方式。通过压缩存储质因子避免了溢出,并在解压过程中支持取模运算。博客提供了完整的C++代码示例。

924

被折叠的 条评论
为什么被折叠?



