1. 程式人生 > >9.29模擬賽

9.29模擬賽

枚舉 等價 gcd 同時 style 9.png spa 內部 com

T1:

技術分享圖片

【數據範圍】

40%的數據滿足 A<=105

另有30%的數據滿足N,M<=109 |S|,|T|<=10(|S|表示S的長度);

100%的數據滿足 N,M<=109 |S|,|T|<=106

先求循環節內,即lcm(S,T)內,匹配數出現次數。

然後乘上循環次數即可。

就是S,T內對d=gcd(S,T)同余的位置的相等字符對數的數量。

可以證明.

證明:

設S長度為l1,T長度為l2

如果一個S中位置a的字符和T中位置b的字符相同。

如果可以在循環節內匹配上的話。

那麽滿足存在k1,k2:a+k1*l1=b+k2*l2

我們現在要找,k1,k2是否存在,有幾個。

移項:k1*l1-k2*l2=b-a;

有解條件是:d=gcd(l1,l2)|(b-a),否則k1,k2不存在

(b-a的正負對解的有無無關緊要,假設是正數)

假設有解,設x=(b-a)/d;

那麽,同時除以d,可以有:k1*l1‘-k2*l2‘=x;

其中,l1‘,l2‘互質。

那麽就有,k1*l1‘=x+k2*l2‘

有:k1*l1‘=x mod (l2‘)

並且,由於x小於l2‘,所以,如果存在一個非負整數k1,符合方程,那麽一定有一個唯一的非負整數的k2

所以等價於同余方程k1*l1‘=x mod (l2‘)的k1有幾個非負整數解。

由於l1‘,l2‘互質,所以,存在一個小於l2‘的k1=x*l1‘^(-1) mod (l2‘)

那麽,這個k1能否加上若幹倍的l2‘呢?

發現,

其實現在k1有了一個條件

因為現在是在循環節的內部,而0<=a<l1;

而lcm=l2‘*l1

所以,0<=k1<l2‘,否則就超出了lcm

由於l1‘,l2‘互質,所以,存在一個k1=x*l1‘^(-1) mod (l2‘)

而k1不能大於等於l2‘,所以,這個k1有且只有一個。

現在我們證明了,

d=gcd(l1,l2)|(b-a)時,在循環節內有且只有一次a,b匹配的機會。

所以,我們可以枚舉字符char∈a~z

把字符都是char的兩個位置 b,a關於d的余數分類。

余數相同的ai,bi位置一定會匹配一次。因為做差一定是d的倍數。

所以,我們可以每次掃兩遍S,T把char出現的位置記錄下來。

然後一個同余類個數直接相乘即可。

最後,再乘上循環節循環次數。

代碼:

9.29模擬賽