日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷P3763 [Tjoi2017]DNA 【后缀数组】

發(fā)布時間:2025/3/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷P3763 [Tjoi2017]DNA 【后缀数组】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接

洛谷P3763

題解

后綴數(shù)組裸題
在BZOJ被卡常到哭QAQ

#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (register int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int #define res register using namespace std; const int maxn = 200005,maxm = 100005,INF = 1000000000; inline int read(){res int out = 0,flag = 1; res char c = getchar();while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}return out * flag; } char s[maxn],s2[maxn]; int sa[maxn],rank[maxn],height[maxn],bac[maxn],t1[maxn],t2[maxn],mn[maxn][18],n,m; int bin[50],Log[maxn],lenp,lent; inline void getsa(){int *x = t1,*y = t2; m = 255;for (res int i = 0; i <= m; i++) bac[i] = 0;for (res int i = 1; i <= n; i++) bac[x[i] = s[i]]++;for (res int i = 1; i <= m; i++) bac[i] += bac[i - 1];for (res int i = n; i; i--) sa[bac[x[i]]--] = i;for (res int k = 1; k <= n; k <<= 1){int p = 0;for (res int i = n - k + 1; i <= n; i++) y[++p] = i;for (res int i = 1; i <= n; i++) if (sa[i] - k > 0) y[++p] = sa[i] - k;for (res int i = 0; i <= m; i++) bac[i] = 0;for (res int i = 1; i <= n; i++) bac[x[y[i]]]++;for (res int i = 1; i <= m; i++) bac[i] += bac[i - 1];for (res int i = n; i; i--) sa[bac[x[y[i]]]--] = y[i];swap(x,y);x[sa[1]] = p = 1;for (res int i = 2; i <= n; i++)x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++p);if (p >= n) break;m = p;}for (res int i = 1; i <= n; i++) rank[sa[i]] = i;for (res int i = 1,k = 0; i <= n; i++){if (k) k--;int j = sa[rank[i] - 1];while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) k++;height[rank[i]] = k;}for (res int i = 1; i <= n; i++) mn[i][0] = height[i];REP(j,17) REP(i,n){if (i + bin[j] - 1 > n) break;mn[i][j] = min(mn[i][j - 1],mn[i + bin[j - 1]][j - 1]);} } inline int lcp(int x,int y){int l = rank[x],r = rank[y];if (l > r) swap(l,r); l++;int t = Log[r - l + 1];return min(mn[l][t],mn[r - bin[t] + 1][t]); } void solve(){int ans = 0;for (res int i = 1; i <= lenp - lent + 1; i++){res int j = 1,tmp,cnt = 3;while (cnt && j <= lent){tmp = lcp(i + j - 1,lenp + 1 + j);if (!tmp) j++,cnt--;else j += tmp;}if (j <= lent){j += lcp(i + j - 1,lenp + 1 + j);}if (j > lent){ans++;}}printf("%d\n",ans); } int main(){bin[0] = 1; REP(i,25) bin[i] = bin[i - 1] << 1;Log[0] = -1; REP(i,200000) Log[i] = Log[i >> 1] + 1;int T = read();while (T--){scanf("%s",s + 1); lenp = strlen(s + 1);s[lenp + 1] = 1; s[lenp + 2] = '\0';scanf("%s",s2 + 1); lent = strlen(s2 + 1);strcat(s + 1,s2 + 1);n = lenp + 1 + lent;getsa();solve();}return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/Mychael/p/9049525.html

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的洛谷P3763 [Tjoi2017]DNA 【后缀数组】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。