首页 > 代码库 > HDU 5008 Boring String Problem(后缀数组+二分)
HDU 5008 Boring String Problem(后缀数组+二分)
题目链接
思路 想到了,但是木写对啊....代码 各种bug,写的乱死了....
输出最靠前的,比较折腾...
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>#include <map>using namespace std;#define N 501000#define LL __int64int sa[N],height[N],rank[N];int c[N],wa[N],wb[N];int p[N];int res[N];char str[N];LL sum[N];LL l,r;int bin[31];int minz[22][N];int sz[22][N];void build_sa(int s[],int n,int m){ int i,j,p,*x = wa,*y = wb; for(i = 0;i < m;i ++) c[i] = 0; for(i = 0;i < n;i ++) c[x[i] = s[i]] ++; for(i = 1;i < m;i ++) c[i] += c[i-1]; for(i = n-1;i >= 0;i --) sa[--c[x[i]]] = i; for(j = 1;j <= n;j <<= 1) { p = 0; for(i = n-j;i < n;i ++) y[p++] = i; for(i = 0;i < n;i ++) if(sa[i] >= j) y[p++] = sa[i] - j; for(i = 0;i < m;i ++) c[i] = 0; for(i = 0;i < n;i ++) c[x[y[i]]] ++; for(i = 1;i < m;i ++) c[i] += c[i-1]; for(i = n-1;i >= 0;i --) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p = 1;x[sa[0]] = 0; for(i = 1;i < n;i ++) x[sa[i]] = y[sa[i-1]] == y[sa[i]]&&y[sa[i-1]+j] == y[sa[i]+j]?p-1:p++; if(p >= n) break; m = p; }}void get_height(int s[],int n){ int i,j,k = 0; for(i = 1;i <= n;i ++) rank[sa[i]] = i; for(i = 0;i < n;i ++) { if(k) k--; j = sa[rank[i]-1]; while(s[i+k]==s[j+k]) k ++; height[rank[i]] = k; }}void init(int n){ int i,j; for(i = 1; i <= n; i ++) { minz[0][i] = height[i]; sz[0][i] = sa[i]; } for(i = 1; bin[i] <= n; i ++) { for(j = 1; j + bin[i-1] <= n; j ++) { minz[i][j] = min(minz[i-1][j],minz[i-1][j+bin[i-1]]); sz[i][j] = min(sz[i-1][j],sz[i-1][j+bin[i-1]]); } }}int rmq(int s,int t){ s = rank[s]; t = rank[t]; if(s > t) swap(s,t); s ++; int k = log((t-s+1)*1.0)/log(2.0); return min(minz[k][s],minz[k][t-bin[k]+1]);}int rmq1(int s,int t){ s = rank[s]; t = rank[t]; if(s > t) swap(s,t); s ++; int k = log((t-s+1)*1.0)/log(2.0); return min(sz[k][s],sz[k][t-bin[k]+1]);}void find(LL k,int n){ int str,end,mid,i; str = 1; end = n; while(str < end) { mid = (str + end + 1)/2; if(sum[mid] > k) end = mid - 1; else str = mid; } i = end; if(sum[end] > k) { l = sa[i]; r = sa[i]+k-1; } else if(k == sum[end]) { l = sa[i]; r = n-1; } else { i ++; l = sa[i]; r = sa[i] + k - sum[end] + height[i]-1; } int len = r-l+1; if(i == n) { l ++; r ++; return ; } if(height[i+1] < len) { l ++; r ++; return ; } str = i+1; end = n; while(str < end) { mid = (str + end + 1)/2; if(rmq(sa[i],sa[mid]) < len) end = mid - 1; else str = mid; } if(rmq(sa[i],sa[end]) >= len) { l = min(l,(LL)rmq1(sa[i],sa[end])); r = l+len-1; } l ++; r ++;}int main(){ int i,len,n; LL maxz; for(i = 0; i < 21; i ++) bin[i] = 1<<i; LL v,k; while(scanf("%s",str)!=EOF) { len = strlen(str); for(i = 0;i < len;i ++) { p[i] = str[i]-‘a‘+1; } p[len] = 0; build_sa(p,len+1,30); get_height(p,len); init(len); maxz = 0; for(i = 1;i <= len;i ++) { maxz += len-sa[i]-height[i]; sum[i] = maxz; } scanf("%d",&n); l = r = 0; for(i = 0;i < n;i ++) { scanf("%I64d",&v);// find(v,len);// printf("%I64d %I64d\n",l,r); k = (v^l^r)+1; if(k > maxz) { l = r = 0; } else { find(k,len); } printf("%I64d %I64d\n",l,r); } } return 0;}
HDU 5008 Boring String Problem(后缀数组+二分)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。