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
- hdu 5008 Boring String Problem(后缀数组)
- HDU 5008 Boring String Problem 后缀数组
- hdu 5008 Boring String Problem(后缀数组)
- hdu 5008 Boring String Problem 【后缀数组】
- hdu 5008 Boring String Problem 后缀数组
- HDU 5008 Boring String Problem 后缀数组
- HDU 5008 Boring String Problem 后缀数组 RMQ
- [后缀数组+二分+rmq] hdu 5008 Boring String Problem
- HDU - 5008 Boring String Problem (后缀数组+二分+RMQ)
- HDU 5008 Boring String Problem 二分 + 后缀数组
- 【后缀数组】 HDOJ 5008 Boring String Problem
- hdu 5008 Boring String Problem(后缀自动机构造后缀树)
- hdu 5008(2014 ACM/ICPC Asia Regional Xi'an Online ) Boring String Problem(后缀数组&二分)
- hdu5008 Boring String Problem 后缀数组+二分
- hdu5008-Boring String Problem(后缀数组专题)
- hdu5008 Boring String Problem(后缀数组)
- 后缀数组 - hdu5008 Boring String Problem
- hdu 5008 Boring String Problem
- PAT basic 1027(Python版)
- 软工文档总结(二)——文档的概述
- leetcode Maximal Rectangle
- unknown_field_set.h
- 百度云客户端好卡
- hdu 5008 Boring String Problem 【后缀数组】
- 分布式事务 原理及使用范例一则
- common.h
- objectForKey与valueForKey在字典中的区别
- 游戏浅谈2-我是死神
- php中关于mysqli和mysql区别的一些知识点分析
- ROM,DRAM,SRAM,SDRAM的区别
- 穷举法 百钱买百鸡
- 决策树算法