SPOJ
来源:互联网 发布:淘宝评价解释在哪里 编辑:程序博客网 时间:2024/06/03 21:42
SPOJ - LCS2
求多个字符串的最长公共子串。先构造第一个串的后缀自动机,定义一个nl表示当前字符串在该处与后缀自动机匹配的最大长度,ml用于保存所有字符串在该处都能匹配的长度,不断更新。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>#include <bitset>#define INF 0x3f3f3f3f#define eps 1e-6#define PI 3.1415926#define mod 1000000009#define base 2333using namespace std;typedef long long LL;const int maxn = 1e5 + 10;const int maxx = 1e3 + 10;inline void splay(int &v) { v=0;char c=0;int p=1; while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p;}struct Node { Node *pre, *nxt[26]; int step, nl, ml; void Clear() { step = nl = 0; pre = NULL; memset(nxt, NULL, sizeof(nxt)); }} *root, *last;Node st[maxn<<1], *top[maxn<<1], *cur;int cnt[maxn];char str[15][maxn];void init() { cur = st; root = last = cur++; root->Clear();}void extend(int w) { Node *np = cur++, *p = last; np->Clear(); np->step = np->ml = p->step+1; while(p && !p->nxt[w]) p->nxt[w] = np, p = p->pre; if(p == NULL) np->pre = root; else { Node *q = p->nxt[w]; if(q->step == p->step+1) np->pre = q; else { Node *nq = cur++; nq->Clear(); memcpy(nq->nxt, q->nxt, sizeof(q->nxt)); nq->step = nq->ml = p->step+1; nq->pre = q->pre; np->pre = q->pre = nq; while(p && p->nxt[w] == q) p->nxt[w] = nq, p = p->pre; } } last = np;}void solve() { int k = 0; while(scanf("%s", str[k++]) != EOF) {} init(); memset(cnt, 0, sizeof(cnt)); int len = strlen(str[0]); for(int i = 0; i < len; i++) extend(str[0][i]-'a'); for(Node *p = st; p != cur; p++) cnt[p->step]++; for(int i = 1; i <= len; i++) cnt[i] += cnt[i-1]; for(Node *p = st; p != cur; p++) top[--cnt[p->step]] = p; int num = cur-st; for(int i = 1; i < k-1; i++) { int len1 = strlen(str[i]); Node *p = root; for(int j = 0, l = 0; j < len1; j++) { int x = str[i][j]-'a'; if(p->nxt[x]) l++, p = p->nxt[x]; else { while(p && !p->nxt[x]) p = p->pre; if(p == NULL) l = 0, p = root; else l = p->step+1, p = p->nxt[x]; } if(l > p->nl) p->nl = l; } for(int j = num-1; j >= 0; j--) { p = top[j]; if(p->nl < p->ml) p->ml = p->nl; if(p->pre && p->pre->nl < p->nl) p->pre->nl = p->nl; p->nl = 0; } } int ans = 0; for(int i = 0; i < num; i++) ans = max(ans, top[i]->ml); printf("%d\n", ans);}int main() { //srand(time(NULL)); //freopen("kingdom.in","r",stdin); //freopen("kingdom.out","w",stdout); solve();}
阅读全文
1 0
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- HTML5_动画、贺年卡、单线 ul li 实现、导航条
- 论文阅读:Instance-aware Semantic Segmentation via Multi-task Network Cascades
- node 安装
- Spring MVC 传参报错400
- iOS实现在webview页面内点击链接,跳转指定App
- SPOJ
- 安卓工作室 日志设置
- Git常用命令整理记录
- Kubernetes存储之Persistent Volumes简介
- Intellij Idea&Android Studio中iml文件、modules.xml文件作用
- 蛇形填数
- Attention在语音识别中的应用(1)
- 阿里巴巴2016前端开发工程师笔试(二)
- 独立封装简单mvc框架(2)