您的位置:首页 > 其它

bzoj3230: 相似子串

2015-12-27 20:23 411 查看
这里给出了统计有效子串以及确定其第一次出现位置的方式

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: