思路 想到了,但是木写对啊....代码 各种bug,写的乱死了....
输出最靠前的,比较折腾...
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> #include <map> using namespace std; #define N 501000 #define LL __int64 int 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; }