hdu 6704 K-th occurrence ST-half Sheet Chairman suffix array tree

We consider a sub-string must be a prefix of a suffix.

Sort adjacent to their suffix prefix certainly the most similar.

So all of a substring must be some sort of common prefix neighboring suffix.

L substring from the beginning, from Rank [l] start to see both sides of the height is greater than the length of the substring guaranteed, can extend long, it is proved that the number of such sub-strings.

We maintain a minimum height ST table, and then by half to a minimum, some thorny border.

Then we get a height not less than the length of the substring successive interval is the interval of the original lexicographical ordering suffix.

While, sa array labeled sorting, the original value of the string position.

So we did this interval on the sa array Chairman tree, find the first large k, k is the position of the first substring that appears.

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cmath>
  5 using namespace std;
  6 const int MAXN = 101000;
  7 char str[MAXN];
  8 int len,q,T,m,uni[30];
  9 struct ktree
 10 {
 11     int n,cnt;
 12     int root[MAXN];
 13     int ls[MAXN * 40],rs[MAXN * 40],s[MAXN * 40 ];
 14  // insert a new version, the parameters are about range, the most recent version of history, the current version, insert the value
 15  // number k value plus the distribution of a reference can perfectly handle the new child node.
16  // S array record number corresponding to the number of elements in the subtree 
. 17      void INSERT ( int L, int R & lt, int pre, int & K, int V)
 18 is      {
 . 19          K = ++ CNT;
 20 is          S [K] S = [pre] + . 1 ;
 21 is          IF (L == R & lt)
 22 is              return ;
 23 is          int MID = (L + R & lt) >> . 1 ;
24          // As we pass a reference to the reference value of k, so here you can directly assign the value of all the nodes around. 
25          LS [K] = LS [pre];
 26 is          RS [K] = RS [pre];
 27          // performed recursively according to the situation around. 
28          IF (V <= MID)
 29              INSERT (L, MID, LS [pre], LS [K], V);
 30          the else 
31 is              INSERT (MID + . 1 , R & lt, RS [pre], RS [K], V );
 32      }
 33  // query x, y two revisions weights segment tree subtraction obtained new segment tree is k-th largest
 34  // here we consider, if we find the interval [x, y] the k-th largest. Then obviously the first x-1 version is equivalent to [1, x-1] weights tree line, then we use the first version of the tree line y - x-1 the first version of the tree line, to get the equivalent of [x , y] section to get weights tree line, then we can be happy query tree line tree. 
35      int ask(int l,int r,int k,int x,int y)
 36     {
 37         if (l == r)
 38             return l;
 39         int mid = (l + r) >> 1;
 40         if (s[ls[y]] - s[ls[x]] >= k)
 41             return ask(l,mid,k,ls[x],ls[y]);
 42         return ask(mid + 1,r,k - (s[ls[y]] - s[ls[x]]),rs[x],rs[y]);
 43     }
 44     void build(int _n,int *vec)
 45     {
 46         n = _n;
 47         for (int i = 1; i <= n; i++)
 48             insert(1,n,root[i - 1],root[i],vec[i]);
 49     }
 50     void clear()
 51     {
 52         for (int i = 1; i <= cnt; i++)
 53             s[i] = ls[i] = rs[i] = 0;
 54         for (int i = 0; i <= n; i++)
 55             root[i] = 0;
 56         n = 0;
 57         cnt = 0;
 58     }
 59 } kt;
 60 struct suffixvec
 61 {
 62     int c[MAXN],sa[MAXN],rnk[MAXN],height[MAXN],tp[MAXN];
 63     int m,len;
 64     char str[MAXN];
 65     void build(int _len,char *s)
 66     {
 67         len = _len;
 68         strcpy(str + 1,s + 1);//因为要从1开始 
 69     }
 70     void clear()
 71     {
 72         for (int i = 1; i <= len; i++)
 73             sa[i] = rnk[i] = height[i] = 0;
 74     }
 75     void qsort()
 76     {
 77         for (int i = 0; i <= m; i++)
 78             c[i] = 0;
 79         for (int i = 1; i <= len; i++)
 80             c[rnk[i]]++;
 81         for (int i = 1; i <= m; i++)
 82             c[i] += c[i - 1];
 83         for (int i = len; i >= 1; i--)
 84             sa[c[rnk[tp[i]]]--] = tp[i];
 85     }
 86     void get_sa()
 87     {
 88         m = 200;
 89         for (int i = 1; i <= len; i++)
 90         {
 91             rnk[i] = str[i];
 92             tp[i] = i;
 93         }
 94         qsort();
 95         for (int k = 1,p = 0; p < len; m = p,k <<= 1)
 96         {
 97             p = 0;
 98             for (int i = 1; i <= k; i++)
 99                 tp[++p] = len - k + i;
100             for (int i = 1; i <= len; i++)
101                 if (sa[i] > k)
102                     tp[++p] = sa[i] - k;
103             qsort();
104             swap(tp,rnk);
105             rnk[sa[1]] = p = 1;
106             for (int i = 2; i <= len; i++)
107                 rnk[sa[i]] = (tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i - 1] + k] == tp[sa[i] + k]) ? p : ++p;
108         }
109     }
110     int solve(int x,int y)
111     {
112         int res = 0;
113         while (str[x++] == str[y++])
114             res++;
115         return res;
116     }
117     void get_height()
118     {
119         int cur = 0;
120         for (int i = 1; i <= len; i++)
121         {
122             if (cur != 0)
123                 cur--;
124             height[rnk[i]] = cur = cur + solve(i + cur,sa[rnk[i] + 1] + cur);
125         }
126     }
127 } sf;
128 struct stable
129 {
130     int p[MAXN][30];
131     int len;
132     void init(int _len,int *vec)
133     {
134         len = _len;
135         int tp = log2(len);
136         for (int i = 1; i <= len; i++)
137             p[i][0] = vec[i];
138         for (int i = 1; i <= tp; i++)
139             for (int j = 1; j + uni[i] - 1 <= len; j++)
140                 p[j][i] = min(p[j][i - 1],p[j + uni[i - 1]][i - 1]);
141     }
142     int querymin(int l,int r)
143     {
144         int tp = log2(r - l + 1);
145         return min(p[l][tp],p[r - uni[tp] + 1][tp]);
146     }
147 } st;
148 int tdl(int x,int lt)
149 {
150     int l = 1,r = x;
151     while (l < r)
152     {
153         int mid = l + r >> 1;
154         if (st.querymin(mid,x) >= lt)
155             r = mid;
156         else
157             l = mid + 1;
158     }
159     return l;
160 }
161 int tdr(int x,int lt)
162 {
163     int l = x,r = len;
164     while (l < r)
165     {
166         int mid = l + r + 1 >> 1;
167         if (st.querymin(x,mid) >= lt)
168             l = mid;
169         else
170             r = mid - 1;
171     }
172     return l;
173 }
174 
175 int main()
176 {
177     uni[0] = 1;
178     for (int i = 1; i <= 25; i++)
179         uni[i] = uni[i - 1] << 1;
180     for(scanf("%d",&T); T != 0; T--)
181     {
182         scanf("%d%d",&len,&q);
183         scanf("%s",str + 1);
184         sf.clear();
185         sf.build(len,str);
186         sf.get_sa();
187         sf.get_height();
188         st.init(sf.len,sf.height);
189         kt.clear();
190         kt.build(len,sf.sa);
191         int l,r,k,tl,tr;
192         for (int i = 1; i <= q; i++)
193         {
194             scanf("%d%d%d",&l,&r,&k);
195             if (sf.height[sf.rnk[l] - 1] < r - l + 1)
196                 tl = sf.rnk[l];
197             else
198                 tl = tdl(sf.rnk[l] - 1,r - l + 1);
199             if (sf.height[sf.rnk[l]] < r - l + 1)
200                 tr = sf.rnk[l];
201             else
202                 tr = tdr(sf.rnk[l],r - l + 1) + 1;
203             if (k > kt.s[kt.root[tr]] - kt.s[kt.root[tl - 1]])
204                 printf("-1\n");
205             else
206                 printf("%d\n",kt.ask(1 , flax, k, kt.root [TL - 1 ] kt.root [tr]));
207          }
 208      }
 209      return  0 ;
210 }

 

Guess you like

Origin www.cnblogs.com/iat14/p/11402468.html