显示代码纯文本
#include <cstring>
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
template<typename T>
inline void read(T &x) {
char ch; while((ch = getchar()), (ch < '0' || ch > '9'));
x = ch - '0'; while((ch = getchar()), (ch >= '0' && ch <= '9')) x = x * 10 + (ch - '0');
}
inline void read01(char *str) {
char ch; while((ch = getchar()), (ch < '0' || ch > '1'));
*(str++) = ch - '0'; while((ch = getchar()), (ch >= '0' && ch <= '1')) *(str++) = ch - '0';
}
const int MAXN = 100010;
const int MAXLEN = 40;
const int MAXNODE = MAXN * MAXLEN + 10;
char str[MAXN];
int N, NQ, maxpos[MAXLEN + 5];
namespace trie {
int ch[MAXNODE][2], pos[MAXNODE], pool = 1;
inline void ins(int x) {
int i, u = 0; char c;
for(i = x; i <= min(N, x + MAXLEN - 1); i++) {
c = str[i];
if(!ch[u][c]) ch[u][c] = pool++;
u = ch[u][c];
if(pos[u]) maxpos[i - x + 1] = max(maxpos[i - x + 1], pos[u]);
pos[u] = max(pos[u], x);
}
}
}
struct query {
int id, L, R;
inline bool operator<(query rhs) const {
return R < rhs.R;
}
} Q[MAXN];
ll Ans[MAXN];
int main() {
freopen("supply.in", "rt", stdin);
freopen("supply.out", "wt", stdout);
int i, p = 1, k;
read(N); read(NQ); read01(str + 1);
for(i = 1; i <= NQ; i++) read(Q[i].L), read(Q[i].R), Q[i].id = i;
sort(Q+1, Q+NQ+1);
for(i = 1; i <= N; i++) {
trie::ins(i);
while(p <= NQ && Q[p].R == i) {
for(k = 1; k <= MAXLEN; k++) {
if(maxpos[k] < Q[p].L) break;
Ans[Q[p].id] += (ll)k * (maxpos[k] - max(maxpos[k + 1], Q[p].L - 1));
}
p++;
}
}
for(i = 1; i <= NQ; i++) printf("%lld\n", Ans[i]);
}