http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4629

后缀数组或扩展kmp

SA做法

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <ctime>
#include <bitset>
#include <iomanip>
#pragma comment(linker, "/STACK:102400000,102400000")using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::stringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;
using std::unique;
using std::lower_bound;
using std::random_shuffle;
using std::bitset;
using std::upper_bound;
using std::multiset;
using std::ios;
using std::make_heap;
using std::push_heap;
using std::pop_heap;typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned UN;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;
typedef long double LF;const int MAXN(200010);
const int MAXM(20010);
const int MAXE(2100010);
const int MAXK(6);
const int HSIZE(1313131);
const int SIGMA_SIZE(26);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const ULL BASE(31);
const LL LIM(1e13);
const int INV(-10000);
const int MOD(1000000007);
const double EPS(1e-7);
const LF PI(acos(-1.0));template<typename T> inline bool checkmax(T &a, T b){if(b > a) { a = b; return true;} return false;}
template<typename T> inline bool checkmin(T &a, T b){if(b < a) { a = b; return true;} return false;}
template<typename T> inline T ABS(T a){return a < 0? -a: a;}
template<typename T> inline bool EZ(T a){return ABS(a) < EPS;}int Log[MAXN];
void initLog(){Log[0] = -1;for(int i = 1; i < MAXN; ++i) Log[i] = (i&(i-1))? Log[i-1]: Log[i-1]+1;
}struct SA{char S[MAXN];int sa[MAXN], t1[MAXN], t2[MAXN], cnt[MAXN], len, M;void init(int l, int m = 128){len = l;M = m;int *p1 = t1, *p2 = t2;for(int i = 0; i < M; ++i) cnt[i] = 0;for(int i = 0; i <= len; ++i) ++cnt[p1[i] = S[i]];for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];for(int i = len; i >= 0; --i) sa[--cnt[p1[i]]] = i;int temp = 1;for(int k = 1; temp <= len; k <<= 1){temp = 0;for(int i = len-k+1; i <= len; ++i) p2[temp++] = i;for(int i = 0; i <= len; ++i) if(sa[i] >= k) p2[temp++] = sa[i]-k;for(int i = 0; i < M; ++i) cnt[i] = 0;for(int i = 0; i <= len; ++i) ++cnt[p1[p2[i]]];for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];for(int i = len; i >= 0; --i) sa[--cnt[p1[p2[i]]]] = p2[i];swap(p1, p2);temp = 1;p1[sa[0]] = 0;for(int i = 1; i <= len; ++i)p1[sa[i]] = p2[sa[i-1]] == p2[sa[i]] && p2[sa[i-1]+k] == p2[sa[i]+k]? temp-1: temp++;M = temp;}}int rank[MAXN], hei[MAXN];void getHei(){int k = 0;for(int i = 0; i <= len; ++i) rank[sa[i]] = i;for(int i = 0; i < len; ++i){if(k) --k;int j = sa[rank[i]-1];while(S[i+k] == S[j+k]) ++k;hei[rank[i]] = k;}}int dp[MAXH][MAXN];void initRMQ(){for(int i = 1; i <= len; ++i) dp[0][i] = hei[i];for(int i = 1; (1 << i) <= len; ++i)for(int j = 1; j+(1 << i)-1 <= len; ++j)dp[i][j] = min(dp[i-1][j], dp[i-1][j+(1 << (i-1))]);}int lcp(int a, int b){if(a == b) return len-a;if(a == len || b == len) return 0;a = rank[a];b = rank[b];if(a > b) swap(a, b);++a;int temp = Log[b-a+1];return min(dp[temp][a], dp[temp][b-(1 << temp)+1]);}int solve(int ind, int lim){ind = rank[ind];int ret = 0;int l = 0, r = ind;while(l < r){int m = (l+r) >> 1;if(lcp(sa[m], sa[ind]) >= lim) r = m;else l = m+1;}ret += ind-l+1;l = ind, r = len+1;while(l < r){int m = (l+r) >> 1;if(lcp(sa[m], sa[ind]) >= lim) l = m+1;else r = m;}--l;ret += l-ind+1;--ret;return ret;}
} sa1, sa2;int main(){initLog();int TC;scanf("%d", &TC);while(TC--){scanf("%s%s", sa1.S, sa2.S);int len1 = strlen(sa1.S), len2 = strlen(sa2.S);sa1.S[len1] = 1;strcpy(sa1.S+len1+1, sa2.S);sa1.init(len1+len2+1);sa2.init(len2);sa1.getHei();sa2.getHei();sa1.initRMQ();sa2.initRMQ();LL ans = 0;for(int i = 1; i < len2; ++i){LL t1 = sa1.solve(len1+1, i);LL t2 = sa2.solve(0, i);LL t3 = t1-t2;t1 = sa1.solve(len1+1+i, len2-i);t2 = sa2.solve(i, len2-i);ans += t3*(t1-t2);}printf("%lld\n", ans);}return 0;
}

扩展kmp

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <ctime>
#include <bitset>
#include <iomanip>
#pragma comment(linker, "/STACK:102400000,102400000")using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::stringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;
using std::deque;
using std::unique;
using std::lower_bound;
using std::random_shuffle;
using std::bitset;
using std::upper_bound;
using std::multiset;
using std::ios;
using std::make_heap;
using std::push_heap;
using std::pop_heap;typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned UN;
typedef pair<int, int> PAIR;
typedef multimap<int, int> MMAP;
typedef long double LF;const int MAXN(100010);
const int MAXM(20010);
const int MAXE(2100010);
const int MAXK(6);
const int HSIZE(1313131);
const int SIGMA_SIZE(26);
const int MAXH(19);
const int INFI((INT_MAX-1) >> 1);
const ULL BASE(31);
const LL LIM(1e13);
const int INV(-10000);
const int MOD(1000000007);
const double EPS(1e-7);
const LF PI(acos(-1.0));template<typename T> inline bool checkmax(T &a, T b){if(b > a) { a = b; return true;} return false;}
template<typename T> inline bool checkmin(T &a, T b){if(b < a) { a = b; return true;} return false;}
template<typename T> inline T ABS(T a){return a < 0? -a: a;}
template<typename T> inline bool EZ(T a){return ABS(a) < EPS;}
/*
template<typename TY, int N>
struct EXKMP{TY P[N];int lenp;int next[N];void getnext(){next[0] = lenp;int k = 1, l = 0, a = 1;while(k < lenp && P[k] == P[l]){++k;++l;}next[l] = 1;int i = 2;while(i < lenp){int temp = next[i-a];if(i+temp < k) next[i] = temp;else{checkmax(k, i);l = k-i;while(k < lenp && P[k] == P[l]){++k;++l;}next[i] = l;a = i;}++i;}next[lenp] = 0;}TY T[N];int lent;int extend[N];void getextend(){int i, a, p, j(-1);for(i = 0; i < lent; ++i, --j){if(j < 0 || i+next[i-a] >= p){if(j < 0) j = 0, p = i;while(p < lent && j < lenp && T[p] == P[j]) ++p, ++j;extend[i] = j, a = i;}elseextend[i] = next[i-a];}}
};
*/
template<typename TY, int N>
struct EXKMP
{TY P[N];int lenp;int next[N]; //next[i]表示str[i...len-1] 与 str[0...len-1]的最长公共前缀void getnext(){next[0] = lenp;int k = 1, l = 0, a = 1; //含义: 当前位置, 匹配长度while(k < lenp && P[k] == P[l]){++k;++l;}next[1] = l;int i = 2;while(i < lenp){int temp = next[i-a];if(i+temp < k) next[i] = temp;else{checkmax(k, i);l = k-i;while(k < lenp && P[k] == P[l]){++k;++l;}next[i] = l;a = i;}++i;}next[lenp] = 0;}TY T[N];int lent;int extend[N];void getextend(){int i, a, p, j(-1);for(i = 0; i < lent; ++i, --j){if(j < 0 || i+next[i-a] >= p){if(j < 0) j = 0, p = i;while(p < lent && j < lenp && T[p] == P[j]) ++p, ++j;extend[i] = j, a = i;}else extend[i] = next[i-a];}}
};void rev(char *sp, int len){int l = 0, r = len-1;while(l < r){swap(sp[l], sp[r]);++l;--r;}
}EXKMP<char, MAXN> exk;
int cnt1[MAXN], cnt2[MAXN];int main(){int TC;   scanf("%d", &TC);while(TC--){scanf("%s%s", exk.T, exk.P);exk.lenp = strlen(exk.P);exk.lent = strlen(exk.T);exk.getnext();exk.getextend();memset(cnt1, 0, sizeof(cnt1[0])*(exk.lenp+1));for(int i = 0; i < exk.lent; ++i) ++cnt1[exk.extend[i]];for(int i = exk.lenp-1; i > 0; --i) cnt1[i] += cnt1[i+1];rev(exk.P, exk.lenp);rev(exk.T, exk.lent);exk.getnext();exk.getextend();memset(cnt2, 0, sizeof(cnt2[0])*(exk.lenp+1));for(int i = 0; i < exk.lent; ++i) ++cnt2[exk.extend[i]];for(int i = exk.lenp-1; i > 0; --i) cnt2[i] += cnt2[i+1];LL ans = 0;for(int i = 1; i < exk.lenp; ++i) ans += (LL)cnt1[i]*cnt2[exk.lenp-i];printf("%lld\n", ans);}return 0;
}

Marlon's String zoj3587相关推荐

  1. 【ZOJ3587】Marlon's String——白四爷×KMP 白濑肆の算法完全解读KMP篇 KMP来袭第二弹前缀什么的果然最讨厌了!【1.0%达成!】

    #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> ...

  2. Zoj 3587 Marlon's String (KMP 字符串拼接 前缀出现次数)

    题意:给字符串S,T,找到所有的tetrad (a,b,c,d), Sa..b + Sc..d = T , a≤b and c≤d.也就是把T分成两段,这两段都由S中的子串组成的,求有多少中组合方式( ...

  3. ZOJ 3587 Marlon's String

    KMP,每匹配到一点就记录一下,然后用fail数组把已经匹配到的但是kmp没有记录的点加上.... Marlon's String Time Limit: 2000MS   Memory Limit: ...

  4. ZOJ3587 Marlon's String

    KMP,正着处理一遍,反着处理一遍,但是用递归的方式一个一个统计会超时,最后累加一下比较好= = #include <cstdio> #include <cstring> #i ...

  5. ZOJ3587 Marlon's String KMP技巧处理

    题意:给定一个 T 串,一个 S 串,问由 S 串中的两个子串组成 T 串有多少种方式? 思路:这道题让我搞了好久,举个例子,将T串分成任意两段,那么必然是从中间断开的,即我们就需要在S中寻找和T的前 ...

  6. zoj2587 Marlon's String

    KMP 求子串的每个前缀在母串中出现的次数,然后反转再求一次,然后计算结果即可 PS:ZOJ评测好严格啊,不强制转换类型会WA...就因为这个WA了好久...一定不要偷懒啊!!! #include&l ...

  7. ZOJ 3587 Marlon's String 扩展KMP

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3587 题意:给出两个字符串S和T,S,T<=100000.拿出 ...

  8. zoj 3587 Marlon's String(拓展KMP+dp)

    链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3587 题目大意: 给字符串S,T,   找到所有的tetrad ( ...

  9. [zoj 3587]Marlon's String[kmp]

    题意: Return the amount of tetrad (a,b,c,d) which satisfy Sa..b + Sc..d = T , a≤b and c≤d. 思路: 正反两次kmp ...

最新文章

  1. 傻瓜式动画制作软件_一个傻瓜版的动画制作软件——万彩动画大师
  2. DDD分层架构最佳实践
  3. samtools merge_【生信工具】Samtools 安装与使用 | “十年以后,工具难免沦为朋友”...
  4. loadrunner脚本练习
  5. Java泛型总结---基本用法,类型限定,通配符,类型擦除
  6. 如何把VS Code打造成Java开发IDE?
  7. wrapper 并集如何使用
  8. ODOO从哪里开始??OpenERP的第一根线头儿
  9. 虚拟机VMware的安装
  10. 实数域上的压缩映射不动点原理
  11. 阿里云国际版账号登录不上去,账号被风控怎么办?
  12. 如何解决wmv/asf/asx格式转成mp4/avi/3gp/mpg/flv的问题
  13. 鸿蒙不是Linux也不是安卓
  14. SpringBoot电商项目之购物车下单(沙箱支付)
  15. PS 如何制作 圆角矩形 图片
  16. 用 JAVA 实现画板
  17. 深度学习词汇表(一)
  18. python办公自动化模块_Python自动化办公Excel模块openpyxl原理及用法解析
  19. Android 比Zing 更快的二维码 条形码扫描Zbar
  20. STM32三种BOOT启动模式详解(全网最全)

热门文章

  1. 网页从输入url到呈现页面流程
  2. Android app ADB命令
  3. 第8章 第七天 - 电影网站整合/集成到公众号
  4. 实战电商后端系统(三)—— 以vue-element-admin为基础的前端项目对接后端接口
  5. Spring之配置 multipartResolver 解析器、上传文件、处理文件
  6. 《Tomcat内核设计剖析》勘误表
  7. 深度|从一个故事说起,谈谈企业应用架构的演变史
  8. 阿里云网盘内测资格申请-最新内测资格
  9. 小米 11 Ultra 正式发布,自称 “安卓之光”
  10. python朱庇特_新的朱庇特书