環上k劃分的和的gcd的最大值【gcd基本性質的利用】

環

今早看到的題,想了下會做了,但是覺得這題挺有意思的,於是打算寫一下做法。本題利用了gcd的基本性質:更相減損法以及結合律,平時做gcd的題基本沒用到過這兩性質,而本題對這性質進行了充分利用。

思路:
首先我們考慮給一個序列,我們該怎麼做。
fn=ni=1ai
我們考慮序列的一個k+1 劃分fx1,fx2fx1,fx3fx2,...,fnfxk ,記爲{x1,x2,x3,...,xk1,xk}
A=fx1,B=fx2fx1,C=fx3fx2
現在我們有gcd 的兩條基本但十分重要的性質:
1.gcd 本質是更相減損法,即gcd(A,BA)=gcd(A,B)
2.gcd 滿足結合律,即gcd(gcd(A,B),C)=gcd(A,gcd(B,C))

  gcd(A,B-A,C-B)
 =gcd(gcd(A,B-A),C-B)
 =gcd(gcd(A,B),C-B)
 =gcd(A,gcd(B,C-B))
 =gcd(A,gcd(B,C))
 =gcd(A,B,C)

根據數學歸納法,可以得出結論:序列上的任意一個k+1 劃分{x1,x2,x3,...,xk1,xk} 等價於gcd(fx1,fx2,fx3,...,fxk,fn)
因爲序列的任意一個劃分總是包含fn ,因此答案一定是fn 的約數。
接下來,考慮枚舉gcd 的值g (即枚舉答案,fn 的約數),即fn 的約數(不超過1e4 個),然後計算fimodg=0 的個數,假設爲x 個,則說明1 ~x 的劃分的答案均可爲此值。

瞭解了鏈上的做法,接下來考慮環上的做法。
考慮環上的斷點爲n1 之間,記爲0 ,則答案即鏈上求得的答案。
現在考慮將斷點向右移動x 單位,即fx 屬於最後一個區間,且1 ~x 之間不可能再有斷點,否則我們在之前便已枚舉過。
然後枚舉gcd 的值g ,然後計算x+1 ~n 內滿足fymodg=fxmodgy 的個數。
爲了加速這一過程,考慮先枚舉gcd 的值g ,再枚舉斷點x ,然後看斷點之後滿足fymodg=fxmodgy 的個數。
其實無需真的枚舉斷點,換個角度思考,枚舉斷點等價於枚舉fxmodg 的值,而每個fxmodg 的值只有編號最小的有用,因爲在這樣的x 之後的y 纔會儘可能多。

既然知道是什麼原理了,最後總結一下做法:
1.枚舉gcd 的值g
2.令bi=fimodg
3.對b 排序,然後統計相同的值出現的次數,
4.初始化ans[] ,令值全爲1,
5.假設值爲x 的出現了y 次,則令ans[y]=max(ans[y],x)
6.對ans 更新得後綴最大值。

for ( int i = n ; i >= 1 ; --i ) {
    ans[i-1] = max ( ans[i - 1] , ans[i] ) ;
}

7.第i 行輸出ansi

發佈了718 篇原創文章 · 獲贊 37 · 訪問量 64萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章