QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#197906 | #6419. Baby's First Suffix Array Problem | APJifengc | RE | 3ms | 18588kb | C++14 | 5.4kb | 2023-10-02 21:32:50 | 2023-10-02 21:32:51 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int T, n, q;
char s[MAXN];
int sa[MAXN], rk[MAXN], tmp[MAXN], cnt[MAXN];
int h[MAXN];
void getSuffixArray() {
int m = 255;
for (int i = 1; i <= m; i++) cnt[i] = 0;
for (int i = 1; i <= n; i++) cnt[rk[i] = s[i]]++;
for (int i = 2; i <= m; i++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i--) sa[cnt[rk[i]]--] = i;
for (int w = 1, t = 0; ; m = t, t = 0, w <<= 1) {
for (int i = 1; i <= n; i++) if (i + w > n) tmp[++t] = i;
for (int i = 1; i <= n; i++) if (sa[i] > w) tmp[++t] = sa[i] - w;
for (int i = 1; i <= m; i++) cnt[i] = 0;
for (int i = 1; i <= n; i++) cnt[rk[tmp[i]]]++;
for (int i = 2; i <= m; i++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i--) sa[cnt[rk[tmp[i]]]--] = tmp[i];
swap(tmp, rk), t = 0;
for (int i = 1; i <= n; i++) {
rk[sa[i]] = (tmp[sa[i]] == tmp[sa[i - 1]] && tmp[sa[i] + w] == tmp[sa[i - 1] + w]) ? t : ++t;
}
if (t == n) return;
}
for (int i = 1; i <= n; i++) assert(1 <= sa[i] && sa[i] <= n);
for (int i = 1; i <= n; i++) assert(1 <= rk[i] && rk[i] <= n);
}
void getHeight() {
for (int i = 1; i <= n; i++) h[i] = 0;
for (int i = 1, j = 0; i <= n; i++) {
if (j) j--;
while (s[i + j] == s[sa[rk[i] - 1] + j]) j++;
h[rk[i]] = j;
}
for (int i = 1; i <= n; i++) assert(0 <= h[i] && h[i] <= n);
}
int st[MAXN][17];
void init() {
for (int i = 1; i <= n; i++) st[i][0] = h[i];
for (int j = 1; j <= 16; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
}
int lcp(int i, int j) {
assert(i <= j);
int len = __lg(j - i + 1);
return min(st[i][len], st[j - (1 << len) + 1][len]);
}
struct BinaryIndexTree {
int a[MAXN];
#define lowbit(x) (x & (-x))
void add(int d, int v) {
assert(d);
while (d < MAXN) {
a[d] += v;
d += lowbit(d);
}
}
int query(int d) {
int ret = 0;
while (d) {
ret += a[d];
d -= lowbit(d);
}
return ret;
}
int query(int l, int r) {
if (l > r) return 0;
return query(r) - query(l - 1);
}
} bit;
int ans[MAXN];
int l[MAXN], r[MAXN], k[MAXN];
struct Query {
int l, r, i, k;
bool operator<(const Query &b) const { return l < b.l; }
};
vector<Query> qs[MAXN];
int v[MAXN];
void solve(int l, int r, vector<int> q) {
if (l == r) return;
int mid = (l + r) >> 1;
vector<int> ql, qr;
for (int i : q) if (rk[k[i]] <= mid) ql.push_back(i); else qr.push_back(i);
solve(l, mid, ql), solve(mid + 1, r, qr);
v[mid] = INT_MAX / 2;
for (int i = mid + 1; i <= r; i++) v[i] = min(v[i - 1], h[i]);
for (int i = mid - 1; i >= 1; i--) v[i] = min(v[i + 1], h[i + 1]);
vector<pair<int, int>> opt;
vector<Query> qry;
for (int i : ql) {
int L = max(::r[i] - v[rk[k[i]]] + 1, k[i] + 1), R = ::r[i];
qry.push_back({ L - 1, ::r[i] + 1, i, -1 });
qry.push_back({ R, ::r[i] + 1, i, 1 });
}
for (int i = mid + 1; i <= r; i++) opt.push_back({ sa[i], v[i] + sa[i] });
sort(opt.begin(), opt.end()), sort(qry.begin(), qry.end());
auto it = opt.begin();
for (auto p : qry) {
while (it != opt.end() && it->first <= p.l) bit.add(it->second, 1), it++;
ans[p.i] += p.k * bit.query(p.r, 2 * n);
}
while (it != opt.begin()) it--, bit.add(it->second, -1);
}
int main() {
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
scanf("%d", &T);
if (T != 2) abort();
while (T--) {
scanf("%d%d%s", &n, &q, s + 1);
getSuffixArray();
getHeight();
init();
for (int i = 1; i <= q; i++) scanf("%d%d%d", &l[i], &r[i], &k[i]), ans[i] = 0;
for (int i = 0; i <= n; i++) qs[i].clear();
for (int i = 1; i <= q; i++) {
qs[l[i] - 1].push_back({ rk[k[i]], 0, i, -1 });
qs[r[i]].push_back({ rk[k[i]], 0, i, 1 });
}
for (int i = 1; i <= n; i++) {
bit.add(rk[i], 1);
for (auto p : qs[i]) ans[p.i] += p.k * bit.query(p.l);
}
for (int i = 1; i <= n; i++) bit.add(rk[i], -1);
for (int i = 0; i <= n; i++) qs[i].clear();
for (int i = 1; i <= q; i++) {
int L = 1, R = rk[k[i]];
while (L < R) {
int mid = (L + R) >> 1;
if (lcp(mid + 1, rk[k[i]]) >= r[i] - k[i] + 1) R = mid;
else L = mid + 1;
}
qs[L - 1].push_back({ l[i], k[i] - 1, i, -1 });
qs[rk[k[i]] - 1].push_back({ l[i], k[i] - 1, i, 1 });
}
for (int i = 1; i <= n; i++) {
bit.add(sa[i], 1);
for (auto p : qs[i]) ans[p.i] -= p.k * bit.query(p.l, p.r);
}
for (int i = 1; i <= n; i++) bit.add(sa[i], -1);
vector<int> qq;
for (int i = 1; i <= q; i++) qq.push_back(i);
solve(1, n, qq);
for (int i = 1; i <= q; i++) printf("%d\n", ans[i]);
}
return 0;
}
/*
baaabbabba
1 a 10
2 aaabbabba 2
3 aabbabba 3
4 abba 7
5 abbabba 4
6 ba 9
7 baaabbabba 1
8 babba 6
9 bba 8
X bbabba 5
*/
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 18588kb
input:
2 10 4 baaabbabba 2 8 3 1 1 1 2 3 2 2 5 4 20 3 cccbccbadaacbbbcccab 14 17 16 3 20 17 17 20 18
output:
2 1 2 3 4 15 3
result:
ok 7 numbers
Test #2:
score: -100
Runtime Error
input:
8994 10 10 abaabbaabb 2 8 3 1 8 5 6 9 6 9 9 9 5 10 7 5 7 7 7 8 7 5 6 6 1 9 9 3 9 5 2 1 ab 1 2 1 8 6 bbabaabb 3 7 7 5 7 7 1 5 1 1 4 3 3 5 3 5 5 5 10 3 aababbaaab 3 4 4 6 9 8 4 6 6 7 3 babbaab 5 6 5 3 6 6 1 6 6 9 3 baaaabbba 2 5 2 8 9 8 1 4 4 9 2 babaababa 2 4 4 2 6 3 2 3 ba 1 2 2 1 2 1 2 2 2 10 2 aba...