hdu 5008 Boring String Problem 【后缀数组】

来源:互联网 发布:顾家 芝华仕 知乎 编辑:程序博客网 时间:2024/04/26 21:05

后缀自动机有些时候还是没有后缀数组好用,注意输出0 0 的时候还要让l和r变成0

#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\len"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\len"#define in64 "%lld"#endif/************ for topcoder by zz1215 *******************/#define foreach(c,itr)  for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define pb              push_back#define pf              push_front#define X               first#define Y               second#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define MC(a,b)memcpy(a,b,sizeof(b))#define MAX(a,b)        ((a)>(b)?(a):(b))#define MIN(a,b)        ((a)<(b)?(a):(b))#define read            freopen("out.txt","r",stdin)#define write           freopen("out2.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-6;const double pi = acos(-1.0);const int maxn = 101234;char c[maxn];int sa[maxn];  // 1~len 有效int rk[maxn];   //  0~len-1 有效int height[maxn];  // 2~len 有效int wa[maxn], wb[maxn], wc[maxn], wd[maxn];int cmp(int *r, int a, int b, int l){return r[a] == r[b] && r[a + l] == r[b + l];}void da(char *r, int *sa, int len, int maxc){r[len++] = 0;int i, j, p, *x = wa, *y = wb, *t;for (i = 0; i<maxc; i++) wd[i] = 0;for (i = 0; i<len; i++) wd[x[i] = r[i]]++;for (i = 1; i<maxc; i++) wd[i] += wd[i - 1];for (i = len - 1; i >= 0; i--) sa[--wd[x[i]]] = i;for (j = 1, p = 1; p<len; j *= 2, maxc = p){for (p = 0, i = len - j; i<len; i++) y[p++] = i;for (i = 0; i<len; i++) if (sa[i] >= j) y[p++] = sa[i] - j;for (i = 0; i<len; i++) wc[i] = x[y[i]];for (i = 0; i<maxc; i++) wd[i] = 0;for (i = 0; i<len; i++) wd[wc[i]]++;for (i = 1; i<maxc; i++) wd[i] += wd[i - 1];for (i = len - 1; i >= 0; i--) sa[--wd[wc[i]]] = y[i];for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < len; i++){x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;}}return;}void get_height(char *r, int *sa, int len){int i, j, k = 0;for (i = 1; i <= len; i++) rk[sa[i]] = i;for (i = 0; i < len; height[rk[i++]] = k){for (k ? k-- : 0, j = sa[rk[i] - 1]; r[i + k] == r[j + k]; k++);}return;}int n;i64 have[maxn];i64 hs[maxn];int qsa[20][maxn];int qh[20][maxn];int lg2[maxn];void init_rmq(int st[][maxn],int l,int r){   //从 l 到 r 初始化rmqfor (int step = 1; (1 << step) <= r; step++){for (int i = l; i <= r; i++){if (i + (1 << (step - 1)) <= r){st[step][i] = min //最小查询//max //最大查询(st[step - 1][i], st[step - 1][i + (1 << (step - 1))]);}else{st[step][i] = st[step - 1][i];}}}}int query(int st[][maxn], int l, int r){  //查询 l 到 r 的结果returnmin  //最小查询//max  //最大查询(st[lg2[r - l + 1]][l], st[lg2[r - l + 1]][r - (1 << lg2[r - l + 1]) + 1]); }void start(){da(c, sa, n, 128);get_height(c, sa, n);for (int i = 1; i <= n; i++){have[i] = n - sa[i] - height[i];}hs[0] = 0;for (int i = 1; i <= n; i++){hs[i] = hs[i - 1] + have[i];}for (int i = 1; i <= n; i++){qsa[0][i] = sa[i];qh[0][i] = height[i];}init_rmq(qsa, 1, n);init_rmq(qh, 2, n);}int find(i64 k,int len){if (k > hs[len]){return -1;}else{int l,r;l = 1; r = len;while (l < r){int mid = (l + r) / 2;if (hs[mid] >= k){r = mid;}else{l = mid + 1;}}return l;}}int findsal(int pos,int hh){int l = 1;int r = pos;while (l < r){int mid = (l + r) / 2;int temp = query(qh, mid + 1, pos);if (temp >= hh) {r = mid;}else{l = mid + 1;}}return l;}int findsar(int pos, int hh){int l = pos;int r = n;while (l < r){int mid = (l + r + 1) / 2;int temp = query(qh, pos + 1, mid);if (temp >= hh){l = mid;}else{r = mid - 1;}}return r;}int main(){for (int i = 1; i < 20; i++){if ((1 << i) < maxn){lg2[(1 << i)] = i;}}for (int i = 3; i < maxn; i++){ if (lg2[i] == 0){lg2[i] = lg2[i - 1];}}while (scanf("%s",c)!=EOF){n = strlen(c);start();int Q;cin >> Q;i64 l, r;i64 k, v;l = r = 0;for (int i = 1; i <= Q; i++){//cin >> v;scanf("%I64d", &v);k = (l ^ r ^ v)+1;int pos = find(k,n);if (pos != -1){l = sa[pos];r = n - (hs[pos] - k)-1;int hh = r - l + 1;int ansl = query(qsa, findsal(pos,hh) , findsar(pos, hh)) + 1;int ansr = ansl + hh - 1;l = ansl;r = ansr;printf("%d %d\n", ansl, ansr);}else{puts("0 0");l = r = 0;}}}return 0;}


0 0
原创粉丝点击