【线段树】Interval GCD【线段树维护gcd】

题意:

      长度为N的数列A,以及M条指令(N、M <= 2*1e5),每条指令可能是以下两种之一:

            1.“C l r d”,表示把 A[l],A[l+1],...,A[r] 都加上d。

            2.“Q l r”,表示询问A[l],A[l+1],...,A[r]的最大公约数(GCD)。

      对于每个询问,输出一个整数表示答案。

思路:

      本题有个提示,gcd(x,y) = gcd(x,y-x),gcd(x,y,z) = gcd(x,y-x,z-y)。

      因此可以发现可以维护一个B数组,B[i] = A[i]-A[i-1],因此gcd(A[l],...,A[r]) = gcd(A[l],ask(l+1,r))。

      所以对于add操作,只需要修改B数组中的B[l]和B[r+1],即将区间修改变成了单点修改。

      而A数组的数也需要记下来,加个lazy标记延迟更新即可。

      这里有一个gcd求负数的问题,gcd(a,b) = -gcd(a,-b),并且 a%(-b) = -(a%b)。

总结:

      本题主要问题在于如何将区间更新的操作变成单点更新,因此只需要发现gcd的一个计算公式,即可发现本题需要列出一个差分数组,然后维护差分数组即可。

猜你喜欢

转载自blog.csdn.net/qq_41552508/article/details/83576592