后缀数组可解。使用单调栈优化。

 /* 3415 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxl = 1e5+;
const int maxn = maxl * ;
char as[maxl], bs[maxl];
int a[maxn];
int rank[maxn], height[maxn], sa[maxn];
int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
int S[maxn][];
int K; bool cmp(int *r, int a, int b, int l) {
return r[a]==r[b] && r[a+l]==r[b+l];
} void da(int *r, int *sa, int n, int m) {
int i, j, *x=wa, *y=wb, *t, p; for (i=; i<m; ++i) wc[i] = ;
for (i=; i<n; ++i) wc[x[i]=r[i]]++;
for (i=; i<m; ++i) wc[i] += wc[i-];
for (i=n-; i>=; --i) sa[--wc[x[i]]] = i;
for (j=,p=; p<n; j*=, m=p) {
for (p=,i=n-j; i<n; ++i) y[p++] = i;
for (i=; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i=; i<n; ++i) wv[i] = x[y[i]];
for (i=; i<m; ++i) wc[i] = ;
for (i=; i<n; ++i) wc[wv[i]]++;
for (i=; i<m; ++i) wc[i] += wc[i-];
for (i=n-; i>=; --i) sa[--wc[wv[i]]] = y[i];
for (t=x,x=y,y=t, x[sa[]]=, p=, i=; i<n; ++i)
x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p-:p++;
}
} void calheight(int *r, int *sa, int n) {
int i, j, k = ; for (i=; i<=n; ++i) rank[sa[i]] = i;
for (i=; i<n; height[rank[i++]]=k)
for (k?k--:, j=sa[rank[i]-]; r[i+k]==r[j+k]; ++k);
} void printSa(int n) {
for (int i=; i<=n; ++i)
printf("%d ", sa[i]);
putchar('\n');
} void printHeight(int n) {
for (int i=; i<=n; ++i)
printf("%d ", height[i]);
putchar('\n');
} void solve() {
int n = , nn; for (int i=; ; ++i) {
if (as[i] == '\0') {
nn = i;
break;
}
a[n++] = as[i];
}
a[n++] = ;
for (int i=; ; ++i) {
if (bs[i] == '\0') {
break;
}
a[n++] = bs[i];
}
a[n] = ; da(a, sa, n+, );
calheight(a, sa, n); int top;
__int64 tot, ans = ; // handle as with bs
top = ;
tot = ;
rep(i, , n+) {
if (height[i] < K) {
top = ;
tot = ;
} else {
int cnt = ;
if (sa[i-] < nn) {
++cnt;
tot += height[i] - K + ;
}
while (top && height[i]<=S[top-][]) {
--top;
tot -= 1LL * S[top][] * (S[top][] - height[i]);
cnt += S[top][];
}
S[top][] = height[i];
S[top][] = cnt;
++top;
if (sa[i] > nn)
ans += tot;
}
} tot = ;
top = ;
rep(i, , n+) {
if (height[i] < K) {
tot = ;
top = ;
} else {
int cnt = ;
if (sa[i-] > nn) {
++cnt;
tot += height[i] - K + ;
}
while (top && height[i]<=S[top-][]) {
--top;
tot -= 1LL * S[top][] * (S[top][] - height[i]);
cnt += S[top][];
}
S[top][] = height[i];
S[top][] = cnt;
++top;
if (sa[i] < nn)
ans += tot;
}
} printf("%I64d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif while (scanf("%d", &K)!=EOF && K) {
scanf("%s%s", as, bs);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

数据发生器。

 from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 20
bound = 10**2
lc = list(string.lowercase)
for tt in xrange(t):
k = randint(1, 10)
fout.write("%d\n" % (k))
length = randint(100, 500)
line = ""
for i in xrange(length):
idx = randint(0, 25)
line += lc[idx]
fout.write("%s\n" % line)
length = randint(100, 500)
line = ""
for i in xrange(length):
idx = randint(0, 25)
line += lc[idx]
fout.write("%s\n" % line)
fout.write("0\n") def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()

【POJ】3415 Common Substrings的更多相关文章

  1. poj 3415 Common Substrings(后缀数组+单调栈)

    http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Sub ...

  2. POJ 3415 Common Substrings(后缀数组 + 单调栈)题解

    题意: 给两个串\(A.B\),问你长度\(>=k\)的有几对公共子串 思路: 先想一个朴素算法: 把\(B\)接在\(A\)后面,然后去跑后缀数组,得到\(height\)数组,那么直接\(r ...

  3. 【POJ】1704 Georgia and Bob(Staircase Nim)

    Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...

  4. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  5. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  6. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  7. 【题解】Greatest Common Increasing Subsequence

    [题解]Greatest Common Increasing Subsequence vj 唉,把自己当做DP入门选手来总结这道题吧,我DP实在太差了 首先是设置状态的技巧,设置状态主要就是要补充不漏 ...

  8. 【SPOJ】Longest Common Substring II

    [SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...

  9. 【SPOJ】Longest Common Substring

    [SPOJ]Longest Common Substring 求两个字符串的最长公共子串 对一个串建好后缀自动机然后暴力跑一下 废话 讲一下怎么跑吧 从第一个字符开始遍历,遍历不到了再沿着\(pare ...

随机推荐

  1. java应用uploadify 3.2丢失session

    java应用uploadify 3.2丢失session http://c-bai.iteye.com/blog/1829269 uploadify上传用的是一个flash插件. flash中有个bu ...

  2. Knockout.js 初探

    Knockout.js是什么? Knockout是一款很优秀的JavaScript库,它可以帮助你仅使用一个清晰整洁的底层数据模型(data model)即可创建一个富文本且具有良好的显示和编辑功能的 ...

  3. LeetCode 解题报告--202Happy Number

    1 题目描述 Write an algorithm to determine if a number is "happy". A happy number is a number ...

  4. C语言的32个关键字

    由ANSI标准定义的C语言关键字共个: auto double int struct break else long switch case enum register typedef char ex ...

  5. MyEclipse新建Maven工程

    1.File-->New-->Web Project 2.新建文件夹 需要新建4个源文件夹,分别是  src/main/java   src/main/resources   src/te ...

  6. LINQ to XML学习笔记

    一.XML基础知识 1.XML:可扩展标记语言 Extensible Markup Language ,提供了一种保存数据的格式,数据可以通过这种格式很容易地在不同的应用程序之间实现共享. 2.使用X ...

  7. jQuery 点击按钮刷新页面

    //页面加载时绑定按钮点击事件 $(function () { $("#按钮id").click(function () { refresh(); }); }); //点击按钮调用 ...

  8. centos7初步配置

    centos7初步配置 首先安装lrzsz zip/unzip yum -y install lrzsz yum -y install zip unzip 安装vim yum install vim* ...

  9. 总有你需要的之 ios 小技巧 (下)

    图片上绘制文字 写一个UIImage的category NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultPara ...

  10. Oracle 常用操作

    修改数据库表名:rename [old-table] to [new-table]; while循环添加测试数据: declare     i int:=1;     begin     while ...