HAOI2016 找相同字元 SAM

2022-05-08 04:39:10 字數 1869 閱讀 2404

給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。

輸入格式:

兩行,兩個字串s1,s2,長度分別為n1,n2。1 <=n1, n2<= 200000,字串中只有小寫字母

輸出格式:

輸出乙個整數表示答案

輸入樣例#1:

複製

aabb

bbaa

輸出樣例#1: 複製

10
這到題目是vj上一道題目的簡化版

對第乙個串建立自動機 在拓撲一邊球每個狀態串的出現次數

然後然第二個串在樹上跑

記錄一下當強匹配的長度,假設到達狀態p,狀態p中的小於匹配長的串都符合,(注意不是p中的所有串),

然後就是p的所有的fa都符合,為了避免總是向上找fa而tle,所以打乙個lz標記,最後的時候一邊拓撲統計剩下的答案:

1 #include2 #include3 #include4 #include5 #include

6 #include7 #include8 #include9 #include10 #include11

#define mem(a,b) memset(a,b,sizeof a)

12#define sc(a) scanf("%d",&(a))

13#define scc(a,b) scanf("%d %d",&(a),&(b))

14#define ll long long

15using

namespace

std;

1617

18int kd[1000000

];19

const

int n = 200010;20

21struct

dd22

dian[1200000

];28

29int cnt[1200000

];30 ll num[n<<1

];31

int last=1;32

int tot=1

;33 inline void add(int

c)34

3557}58

}59int ans=0

;60 vectorv;

61void

top()

627374}

75 ll lz[n<<1

];76

77void work(string s,int

len)

7890

else

91100

}101

if(now!=1

)102

106107

//cout<<"here: "<108

}109

//cout<<"now: "<110

int sze=v.size();

111for(int i=0; i)

112119

120 cout<121122

123124

125}

126signed main()

127

HAOI2016 找相同字元

給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。兩行,兩個字串s1,s2,長度分別為n1,n2。1 n1,n2 200000,字串中只有小寫字母 題解 s1 s2拼起來。求height 要求 i j lcp rk i rk j ...

HAOI2016 找相同字元

其實這道題跟 ahoi2013 差異很像 其實這個問題的本質就是讓你算所有字尾的 lcp 長度之和,但是得來自兩個不同的字串 先把兩個字串拼起來做一遍 sa 由於我們多算了來自於同乙個串內的情況 於是在分別對這兩個串建 sa 減掉這兩次算出來的答案 現在的問題轉化為求出 height 陣列所有子區間...

HAOI 2016 找相同字元

題目鏈結 演算法 首先 子串是字尾的字首 考慮拼接兩個字串 中間用不可見字元隔開 求出該字串的字尾陣列 那麼字首相同的字尾一定排名一定接近 而我們又知道lcp i j min 維護乙個單調遞增的字尾陣列即可 時間複雜度 o nlogn n a b includeusing namespace std...