博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P3763 [Tjoi2017]DNA 【后缀数组】
阅读量:4598 次
发布时间:2019-06-09

本文共 2895 字,大约阅读时间需要 9 分钟。

题目链接

题解

后缀数组裸题

在BZOJ被卡常到哭QAQ

#include
#include
#include
#include
#include
#include
#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
(a,b)#define cls(s) memset(s,0,sizeof(s))#define cp pair
#define LL long long int#define res registerusing 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;}

转载于:https://www.cnblogs.com/Mychael/p/9049525.html

你可能感兴趣的文章
xp_cmdshell 命令的开启与关闭,和状态查询
查看>>
Linux sudoers
查看>>
MySQL详解(18)-----------分页方法总结
查看>>
bzoj 4595 激光发生器
查看>>
multi cookie & read bug
查看>>
js时间转换
查看>>
(转载) Android Studio你不知道的调试技巧
查看>>
POJ2231 Moo Volume 递推 C语言
查看>>
struts2类型转换的具体流程
查看>>
Hdu 1203 I NEED A OFFER!
查看>>
php文件上传类
查看>>
CF219D Choosing Capital for Treeland
查看>>
luogu P3809 【模板】后缀排序
查看>>
Red Gate 破解
查看>>
JVM 调优工具
查看>>
SCTF 2014 pwn题目分析
查看>>
集合以及特殊集合
查看>>
USACO 2.2 Runaround Numbers
查看>>
利用 force index优化sql语句性能
查看>>
Matlab画图-非常具体,非常全面
查看>>