codechef 真的是太菜了。
上面一道水题,14年之后就没人A了。
以前A的人都是T的,跑的比我慢到不知道到哪里去了。
(还有随便一个全a串就卡成一百多秒的“AC”程序。。。)
发个链接:
我的代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2000005, LOG = 22;
int n, m, tp;
int Rt[N], gr[LOG][N];
char s[N], ssr[13];
LL sum[N];
namespace SE {
const int M = N * 40;
int tot, lc[M], rc[M], sum[M];
void Modify(int &t, int l, int r, int x) {
if (!t) t = ++tot;
++sum[t];
if (l == r) return;
int md = (l + r) >> 1;
if (x <= md) Modify(lc[t], l, md, x);
else Modify(rc[t], md + 1, r, x);
}
int Merge(int x, int y) {
if (!x || !y) return x + y;
int z = ++tot;
lc[z] = Merge(lc[x], lc[y]);
rc[z] = Merge(rc[x], rc[y]);
sum[z] = sum[lc[z]] + sum[rc[z]];
return z;
}
int Query_1(int t, int l, int r, int k) {
if (l == r) return l;
int md = (l + r) >> 1;
if (sum[lc[t]] >= k) return Query_1(lc[t], l, md, k);
return Query_1(rc[t], md + 1, r, k - sum[lc[t]]);
}
int Query_2(int t, int l, int r, int k) {
if (l == r) return sum[t];
int md = (l + r) >> 1;
if (k <= md) return Query_2(lc[t], l, md, k);
return sum[lc[t]] + Query_2(rc[t], md + 1, r, k);
}
}
int tot = 1, lst = 1, ch[N][26], dep[N], rig[N], fa[N], ed[N];
int bit[N], id[N], rk[N], pos[N], son[N][26];
inline int New_(int _dep, int _fa, int _ri, int _e) {
dep[++tot] = _dep; fa[tot] = _fa; rig[tot] = _ri; ed[tot] = _e;
return tot;
}
void Ins(int a, int i) {
int np = New_(dep[lst] + 1, 0, 1, i), p = lst;
lst = np; pos[i] = tot;
SE::Modify(Rt[tot], 1, n, i);
for (; p && !ch[p][a]; p = fa[p]) ch[p][a] = np;
if (!p) return void(fa[np] = 1);
int q = ch[p][a];
if (dep[q] == dep[p] + 1) return void(fa[np] = q);
int y = New_(dep[p] + 1, fa[q], 0, ed[q]);
memcpy(ch[y], ch[q], sizeof ch[y]);
fa[q] = fa[np] = y;
for (; p && ch[p][a] == q; p = fa[p]) ch[p][a] = y;
}
void Dfs(int x) {
//cerr << "vis : " << x << endl;
id[++tp] = x;
for (int i = 0; i < 26; ++i) {
if (son[x][i]) Dfs(son[x][i]);
}
}
void Build() {
for (int i = 1; i <= tot; ++i) ++bit[dep[i]];
for (int i = 1; i <= tot; ++i) bit[i] += bit[i - 1];
for (int i = 1; i <= tot; ++i) id[bit[dep[i]]--] = i;
for (int i = 1; i <= tot; ++i) {
int x = id[i]; gr[0][x] = fa[x];
for (int j = 1; j < LOG; ++j) gr[j][x] = gr[j - 1][gr[j - 1][x]];
}
for (int i = tot; i >= 2; --i) {
int x = id[i], y = fa[x];
rig[y] += rig[x];
Rt[y] = SE::Merge(Rt[x], Rt[y]);
son[y][s[ed[x] - dep[y]] - 'a'] = x;
//cerr << "son : " << y << " -- " << ed[x] - dep[y] << " --> " << x << endl;
}
Dfs(1);
if (tp != tot) { cerr << "not tp equal!" << endl; throw; }
//cerr << "id : ";
for (int i = 1; i <= tot; ++i) {
//cerr << id[i] << ' ';
rk[id[i]] = i;
sum[i] = sum[i - 1] + dep[id[i]] - dep[fa[id[i]]];
}
//cerr << endl << "finish build all" << endl;
}
pair<LL, LL> Solve_1(LL k1, int k2) {
//cerr << "query 1 : " << k1 << ' ' << k2 << endl;
int nl = 1, nr = tot, x = -1;
for (int md; nl <= nr; ) {
md = (nl + nr) >> 1;
if (k1 <= sum[md]) {
x = md; nr = md - 1;
} else {
nl = md + 1;
}
}
if (x == -1) { cerr << "not found po!" << endl; throw; }
k1 -= sum[x - 1];
x = id[x];
//cerr << "now x : " << x << ' ' << rig[x] << endl;
if (k2 > rig[x]) { cerr << "k2" << endl; throw; }
k2 = rig[x] - k2 + 1;
int ps = SE::Query_1(Rt[x], 1, n, k2);
//cerr << "note : " << k2 << ' ' << ps << endl;
int len = k1 + dep[fa[x]];
//cerr << "ans 1 : " << ps - len + 1 << ' ' << ps << endl;
return make_pair(ps - len + 1, ps);
}
pair<LL, LL> Solve_2(int l, int r) {
int x = pos[r], le = r - l + 1;
for (int i = LOG - 1; ~i; --i) {
if (gr[i][x] && dep[gr[i][x]] >= le) x = gr[i][x];
}
//cerr << "x : " << x << endl;
int re = SE::Query_2(Rt[x], 1, n, r);
LL rnk = sum[rk[x] - 1] + le - dep[fa[x]];
//cerr << "note : " << rk[x] << ' ' << le << ' ' << dep[fa[x]] << endl;
return make_pair(rnk, rig[x] - re + 1);
}
int main() {
//freopen("zzz.in", "r", stdin);
//freopen("zzz.out", "w", stdout);
scanf("%s", s + 1);
n = strlen(s + 1);
reverse(s + 1, s + 1 + n);
for (int i = 1; i <= n; ++i) Ins(s[i] - 'a', i);
Build();
scanf("%d", &m);
for (LL l, r; m; --m) {
scanf("%s%lld%lld", ssr, &l, &r);
pair<LL, LL> re;
if (ssr[0] == 'S') {
re = Solve_1(l, r);
re.first = n - re.first + 1;
re.second = n - re.second + 1;
swap(re.first, re.second);
} else {
l = n - l + 1; r = n - r + 1; swap(l, r);
re = Solve_2(l, r);
}
printf("%lld %lld\n", re.first, re.second);
}
return 0;
}