题目链接

洛谷P3763

题解

后缀数组裸题

在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;
}

最新文章

  1. ASP.NET MVC之路由特性以及母版页呈现方式(十二)
  2. Unity 3D 正交相机(Orthographic)
  3. IOS 本地通知推送消息
  4. 【转】MongoDB安全配置
  5. ASP.NET中UEditor使用
  6. 51nod1537 分解
  7. GridView下DropDownList 的选择方法onselectedindexchanged 实现方法
  8. IO流(File类
  9. Effective C++:规定12:不要忘了复制的对象时,它的每一个组成部分
  10. Codeforces.1043F.Make It One(DP 容斥)
  11. [ROS]激光驱动安装
  12. “PurMVC”在Unity中的应用
  13. mktemp 命令
  14. 如何在同一台电脑上启动多个Tomcat服务器
  15. 如何使用Bootstrap自带图标
  16. andorid 三种方式的练习
  17. Windows 安装Rabbitmq
  18. [Android Pro] AndroidStudio IDE界面插件开发(Hello World篇)
  19. 【HTML】input标签中alt属性和title属性的比较
  20. maven pom.xml配置

热门文章

  1. 微信程序跳转到页面底部 scroll-view
  2. 初学tiny4412
  3. zabbix监控MySQL服务状态
  4. Java学习笔记十四:如何定义Java中的类以及使用对象的属性
  5. Linux命令备忘录: jobs 显示Linux中的任务列表及任务状态命令
  6. JAVA 泛型之类型擦除
  7. c++ class as sort function
  8. Qt BarChart实践
  9. nmon Analyser分析仪
  10. 第一篇 Postman的初级使用之设置环境快速切换生成环境与测试环境