acdream1116 Gao the string!(擴充KMP)

來源:互聯網
上載者:User

標籤:blog   http   os   io   for   html   

今天是字串填坑的一天,首先填的第一個坑是擴充KMP。總結一下KMP和擴充KMP的區別。

在這裡s是主串,t是模式串。

KMP可以求出的是以s[i]為結尾的串和 t首碼匹配的最長的長度。假如這個長度是L的話,則:

s[i-L+1...i]=t[0...L]

而所謂的失配指標f[i]指的就是當前i點失配時要匹配的長度,實際是用t文本串去匹配t。

擴充KMP則是以s[i]為起始的串和 t首碼匹配的最長的長度。 假如這個長度的話,則:

s[i..i+L-1]=t[0...L]

擴充KMP裡的nxt數組就是利用t本身和自己匹配達到的效果。所以nxt[i]就是以t的尾碼i和t的首碼匹配的最長的長度,有了這個就可以用來求上次的這道題了。

自己寫的時候寫了個尾碼數組的版本,可以將t的首碼理解成尾碼0,於是就是尾碼之間的最長首碼,就是利用lcp來求,無奈的是尾碼數組本身求的速度太慢了,rmq的速度更慢。由於擴充KMP是線性,所以這次就可以順利的過了這道坑爹題了。

下面第一個網裡有一些理論的證明,但KMP那部分和我學的不太一樣,不知道是我搞錯了還是版本不一樣,然後第二個連結裡的代碼感覺寫的可讀性強一點,在這裡存一下模板。

http://www.cnblogs.com/10jschen/archive/2012/09/03/2668149.html 

http://www.cnblogs.com/kuangbin/archive/2012/08/27/2659246.html

#pragma warning(disable:4996)#include <iostream>#include <cstring>#include <string>#include <vector>#include <cmath>#include <cstdio>#include <algorithm>using namespace std;#define ll long long#define mxs 1000000 #define mxt 100000#define mod 1000000007char s[mxs], t[mxt];int nxt[mxt], ex[mxt];// get the next array for t onlyvoid getNext(char *t,int *nxt){int m = strlen(t);nxt[0] = m;int j = 0;while (j + 1 < m&&t[j] == t[j + 1]) j++;nxt[1] = j;int k = 1; int p, L;for (int i = 2; i < m; i++){p = nxt[k] + k - 1;L = nxt[i - k];if (i + L < p + 1) nxt[i] = L; // i+L<=pelse{j = max(0, p - i + 1);while (i + j < m&&t[i + j] == t[0 + j])j++;nxt[i] = j;k = i;}}}// get the next array for t, and get the ex array for s;void getExtend(char *s, char *t, int *nxt, int *ex){getNext(t, nxt);int n = strlen(s), m = strlen(t);int j = 0;while (j < n&&j < m&&s[j] == t[j]) j++;ex[0] = j;int k = 0; int p, L;for (int i = 1; i < n; i++){p = ex[k] + k - 1;L = nxt[i - k];if (i + L < p + 1) ex[i] = L;else{j = max(0, p - i + 1);while (i + j < n&&j < m&&s[i + j] == t[j]) j++;ex[i] = j;k = i;}}}struct Matrix{ll a[2][2];Matrix(){ memset(a, 0, sizeof(a)); }}m;Matrix operator * (const Matrix &a, const Matrix &b){Matrix ret;for (int i = 0; i < 2; i++){for (int j = 0; j < 2; j++){for (int k = 0; k < 2; k++){ret.a[i][j] += (a.a[i][k] * b.a[k][j]) % mod;ret.a[i][j] %= mod;}}}return ret;}Matrix operator ^ (Matrix a, ll n){Matrix ret;for (int i = 0; i < 2; i++) ret.a[i][i] = 1;while (n){if (n & 1) ret = ret*a;n >>= 1;a = a*a;}return ret;}ll cal(ll n){m.a[0][0] = 0; m.a[0][1] = 1;m.a[1][0] = 1; m.a[1][1] = 1;m = m^n;return m.a[0][1];}int main(){while (~scanf("%s",s)){getNext(s, nxt);int n = strlen(s);nxt[n] = 0;ll ans = 0;for (int i = n - 1; i >= 0; i--){nxt[i] += nxt[i + 1];ans += cal(nxt[i]);ans %= mod;}printf("%lld\n", ans);}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.