1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <cstdio> #include <algorithm> #include <cstring> #include <cctype> #include <set> using namespace std; inline int read(int f = 1, int x = 0, char ch = ' ') { while(!isdigit(ch = getchar())) if(ch == '-') f = -1; while(isdigit(ch)) x = x*10+ch-'0', ch = getchar(); return f*x; } const int N = 2e5+5; int last = 1, tot = 1, ch[N][2], fa[N], len[N]; int m, p[N], tax[N]; set<int> t[N]; char s[N]; void insert(int c) { int cur = ++tot, pre = last; last = cur; len[cur] = len[pre]+1; t[cur].insert(len[cur]); while(pre&&!ch[pre][c]) ch[pre][c] = cur, pre = fa[pre]; if(!pre) return void(fa[cur] = 1); int x = ch[pre][c]; if(len[pre]+1 == len[x]) return void(fa[cur] = x); int y = ++tot; fa[y] = fa[x]; fa[x] = fa[cur] = y; len[y] = len[pre]+1; memcpy(ch[y], ch[x], sizeof(ch[x])); while(pre&&ch[pre][c] == x) ch[pre][c] = y, pre = fa[pre]; } int n, q; int ans[N]; struct Tup { int w[3]; Tup(int x = 0, int y = 0, int z = 0){ w[0] = x; w[1] = y; w[2] = z; } int operator [] (const int x) { return w[x]; } bool operator < (const Tup &_) const { for(int i = 0; i < 3; ++i) if(w[i] != _.w[i]) return w[i] < _.w[i]; return true; } }tup[N<<6], par[N]; int val[N]; void change(int x, int d) { for( ; x; x -= x&-x) val[x] = max(val[x], d); } int query(int x) { int ret = 0; for( ; x <= n; x += x&-x) ret = max(ret, val[x]); return ret; } int main() { scanf("%d%d", &n, &q); scanf("%s", s+1); for(int i = 1; i <= n; ++i) insert(s[i]-'0'); for(int i = 1; i <= tot; ++i) ++tax[len[i]]; for(int i = 1; i <= tot; ++i) tax[i] += tax[i-1]; for(int i = 1; i <= tot; ++i) p[tax[len[i]]--] = i; for(int i = tot; i > 1; --i) { int x = p[i]; if(t[x].size() > t[fa[x]].size()) swap(t[x], t[fa[x]]); set<int>::iterator it, a, b, c; for(it = t[x].begin(); it != t[x].end(); ++it) { t[fa[x]].insert(*it); a = b = c = t[fa[x]].find(*it); ++c; if(a != t[fa[x]].begin()) --a, tup[++m] = Tup(*b, *a, len[fa[x]]); if(c != t[fa[x]].end()) tup[++m] = Tup(*c, *b, len[fa[x]]); t[fa[x]].erase(*it); } for(it = t[x].begin(); it != t[x].end(); ++it) t[fa[x]].insert(*it); } sort(tup+1, tup+1+m); for(int i = 1; i <= q; ++i) { int l = read(), r = read(); par[i] = Tup(r, l, i); } sort(par+1, par+1+q); for(int i = 1, ptr = 1; i <= q; ++i) { while(ptr <= m&&tup[ptr][0] <= par[i][0]) change(tup[ptr][1], tup[ptr][2]), ++ptr; ans[par[i][2]] = query(par[i][1]); } for(int i = 1; i <= q; ++i) printf("%d\n", ans[i]); return 0; }
|