bzoj3230: 相似子串
2015-12-27 20:23
411 查看
这里给出了统计有效子串以及确定其第一次出现位置的方式
View Code
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> using namespace std; void setIO(const string& s) { freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout); } template<typename Q> Q read(Q& x) { static char c, f; for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1; for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; if(f) x = -x; return x; } template<typename Q> Q read() { static Q x; read(x); return x; } typedef long long LL; const int N = 100000 + 10, INF = ~0u >> 1; char s ; int n, Log2 ; struct SuffixArray { int sa ; void build_sa(const char *s, int m = 256) { static int t1 , t2 , c ; int *x = t1, *y = t2; for(int i = 0; i < m; i++) c[i] = 0; for(int i = 0; i < n; i++) c[x[i] = s[i]]++; for(int i = 1; i < m; i++) c[i] += c[i-1]; for(int i = 0; i < n; i++) sa[--c[x[i]]] = i; for(int k = 1; k < n; k <<= 1) { int p = 0; for(int i = n - k; i < n; i++) y[p++] = i; for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k; for(int i = 0; i < m; i++) c[i] = 0; for(int i = 0; i < n; i++) c[x[i]]++; for(int i = 1; i < m; i++) c[i] += c[i-1]; for(int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; p = 1, swap(x, y), x[sa[0]] = 0; for(int i = 1; i < n; i++) { x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && (sa[i-1]+k < n ? y[sa[i-1]+k] : -1) == (sa[i]+k < n ? y[sa[i]+k] : -1)) ? p-1 : p++; } if(p >= n) break; m = p; } } int rank , height ; void build_height(const char *s) { for(int i = 0; i < n; i++) rank[sa[i]] = i; for(int k = 0, i = 0; i < n; i++) { if(k) k--; if(!rank[i]) continue; int j = sa[rank[i]-1]; while(s[i+k] == s[j+k]) k++; height[rank[i]] = k; } } LL s ; void build_s() { s[0] = n - sa[0]; for(int i = 1; i < n; i++) { s[i] = s[i-1] + n - sa[i] - height[i]; } } int f [17]; void rmq_init() { for(int i = 1; i < n; i++) f[i][0] = height[i]; for(int j = 1; (1 << j) < n; j++) { for(int i = 1; i + (1 << (j-1)) < n; i++) { f[i][j] = min(f[i][j-1], f[i + (1 << (j-1))][j-1]); } } } int rmq(int a, int b) { a = rank[a], b = rank[b]; if(a > b) swap(a, b); ++a; int t = Log2[b - a + 1]; return min(f[a][t], f[b - (1 << t) + 1][t]); } void kthstr(LL pos, int& a, int& b) { int x = lower_bound(s, s + n, pos) - s; a = sa[x], b = sa[x] + height[x] + pos - (x ? s[x-1] : 0); } void init(const char *s) { build_sa(s); build_height(s); build_s(); rmq_init(); } }A, B; int main() { #ifdef DEBUG freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif Log2[0] = -1; for(int i = 1; i < N; i++) Log2[i] = Log2[i >> 1] + 1; int m; read(n), read(m); scanf("%s", s); A.init(s); reverse(s, s + n); B.init(s); while(m--) { int a1, a2, b1, b2, t; LL l, r, ans = 0; read(l), read(r); if(l > A.s[n-1] || r > A.s[n-1]) { puts("-1"); continue; } A.kthstr(l, a1, b1); A.kthstr(r, a2, b2); t = (a1 == a2) ? INF : A.rmq(a1, a2); t = min(t, min(b1 - a1, b2 - a2)); ans += (LL) t * t; t = (b1 == b2) ? INF : B.rmq(n - b1, n - b2); t = min(t, min(b1 - a1, b2 - a2)); ans += (LL) t * t; printf("%lld\n", ans); } return 0; }
View Code
相关文章推荐
- Json在线工具使用说明
- 如何在Fedora 17 18 19 20 21 22 23 系统中安装 openjdk 1.6 与 1.7 1.8 共存
- python的模块安装
- linux动态库和静态库
- Genymotion error:The virtual device got no IP address
- CentOS/Linux 网卡设置 IP地址配置永久生效
- Dreamweaver 中文乱码
- iOS界面设计指南
- Hibernate映射问题
- Centos6.7搭建Rsyslog日志服务器
- 中断处理
- SpringMVC返回数据方式
- dom高级程序设计学习
- 02.cocos2d-x触摸事件(一)
- 检测主机是否在线小脚本
- 关于嵌套图片标签的问题
- 2015福建省赛 fzoj Super Mobile Charger 2212 (转换)
- 学生信息管理系统问题篇
- php5.3 appache phpstudy win7win8win10下 运行速度慢解决办法
- 关于菜单栏的相应