1. 程式人生 > >【線段樹】Interval GCD【線段樹維護gcd】

【線段樹】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的一個計算公式,即可發現本題需要列出一個差分陣列,然後維護差分陣列即可。