UNR #10 D1T3 补题记录
完全想不到倍增分块啊。
考虑一个 \((l, k)\) 的判定,我们取出最大的 \(b\) 满足 \(2^b \le k - l\),比较 \(s[l: l + 2^b - 1]\) 和 \(s^R [k - 2 ^ b + 1, k]\) 即可得知 \(k\) 是否合法。
这样一次询问 \([l, r]\) 的求解分为了 \(b = 0, 1, \dots, b'\) 左端点为 \(l\) 的问题,最后一段可能不完整。
所有后缀和前缀一起排序,采用倍增的方法排序,可以得知每个长为 \(2 ^ b\) 的子串的排序结果。
然后排名的偏序用线段树维护,时间复杂度为 \(\mathcal O(n\log ^ 2n + q\log n)\)。
点击查看代码
#include <bits/stdc++.h>
#define ll int
#define LL long long
#define pir pair <ll, ll>
#define fi first
#define se second
#define mkp make_pair
#define pb push_back
#define i128 __int128
#define uLL unsigned LL
#define For(i, a, b) for(ll i = a; i <= b; i++)
#define DFor(i, a, b) for(ll i = a; i >= b; i--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template <class T1, class T2> void chkmax(T1 &x, const T2 y) { x = x < y? y : x; }
template <class T1, class T2> void chkmin(T1 &x, const T2 y) { x = x < y? x : y; }
template <class T> void rd(T &x) {
char ch; bool f = 0;
while(!isdigit(ch = getchar()))
if(ch == '-') f = 1;
x = ch - '0';
while(isdigit(ch = getchar()))
x = (x << 1) + (x << 3) + ch - '0';
if(f) x = -x;
}
const ll maxn = 4e5 + 10, M = 2e6 + 10, mod = 998244353;
template <class T1, class T2>
void add(T1 &x, const T2 y) { x = x + y >= mod? x + y - mod : x + y; }
template <class T1, class T2>
void sub(T1 &x, const T2 y) { x = x < y? x + mod - y : x - y; }
template <class T1, class T2>
ll pls(const T1 x, const T2 y) { return x + y >= mod? x + y - mod : x + y; }
template <class T1, class T2>
ll mus(const T1 x, const T2 y) { return x < y? x + mod - y : x - y; }
using namespace std;
ll _, n, q, _q, e, L[M], R[M], sa[maxn], rk[maxn], oldrk[maxn << 1], cnt[maxn], id[maxn];
char str[maxn];
uLL w, a[maxn], ans[M];
void report() {
uLL ret = 0;
// For(i, 1, q) debug("%llu\n", ans[i]);
For(i, 1, q) ret ^= ans[i] + (uLL) i * i * i;
printf("%llu\n", ret); exit(0);
}
vector <ll> vec[20], sec[maxn];
struct Data { uLL prod, sum; } res[maxn];
const Data operator + (const Data a, const Data b) {
return (Data) {a.prod * b.prod, a.sum + b.sum * a.prod};
}
struct SGT {
Data t[maxn << 2];
void modify(ll p, ll l, ll r, ll x) {
if(l == r) return t[p] = (Data) {w, a[l]}, void();
ll mid = l + r >> 1;
if(x <= mid) modify(p << 1, l, mid ,x);
else modify(p << 1|1, mid + 1, r, x);
t[p] = t[p << 1] + t[p << 1|1];
}
Data ask(ll p, ll l, ll r, ll ql, ll qr) {
if(ql <= l && r <= qr) return t[p];
if(qr < l || r < ql) return (Data) {1, 0};
ll mid = l + r >> 1;
return ask(p << 1, l, mid, ql, qr) + ask(p << 1|1, mid + 1, r, ql, qr);
}
} tr;
int main() {
rd(_), rd(n), rd(w), rd(q), rd(_q), rd(e), scanf("%s", str + 1);
For(i, 1, n) rd(a[i]);
mt19937 rng(e);
auto rnd = [&](unsigned L, unsigned R) -> unsigned {
uLL range = (uLL) R - L + 1;
unsigned bucket = (1ull << 32) / range;
uLL limit = bucket * range;
uLL v;
do {
v = rng();
} while((uLL) v >= limit);
return L + (unsigned) ((uLL) v / bucket);
};
For(o, 1, q) {
ll l, r;
if(o <= _q) rd(l), rd(r);
else {
l = rnd(1, n), r = rnd(1, n);
if(l > r) swap(l, r);
}
L[o] = l, R[o] = r;
ll b = 0;
while(l + (1 << b + 1) - 1 <= r) ++b;
vec[b].pb(o);
}
str[n + 1] = 'a' - 1;
For(i, 1, n) str[2 * n - i + 2] = str[i];
ll m = 2 * n + 1;
For(i, 1, m) ++cnt[str[i] - 'a' + 1];
For(i, 1, 26) cnt[i] += cnt[i - 1];
For(i, 1, m) sa[cnt[str[i] - 'a' + 1]--] = i;
ll p = 0;
For(i, 1, m)
if(str[sa[i]] == str[sa[i - 1]]) rk[sa[i]] = p;
else rk[sa[i]] = ++p;
For(i, 1, n) res[i] = (Data) {w, 0};
for(ll w = 1, u = 1; w < n; w <<= 1, ++u) {
p = 0;
For(i, 0, w - 1) id[++p] = m - i;
For(i, 1, m)
if(sa[i] > w) id[++p] = sa[i] - w;
memset(cnt, 0, sizeof cnt);
For(i, 1, m) oldrk[i] = rk[i], ++cnt[rk[i]];
For(i, 1, m) cnt[i] += cnt[i - 1];
DFor(i, m, 1) sa[cnt[rk[id[i]]]--] = id[i];
p = 0;
For(i, 1, m)
if(oldrk[sa[i]] == oldrk[sa[i - 1]] &&
oldrk[sa[i] + w] == oldrk[sa[i - 1] + w]) rk[sa[i]] = p, assert(sa[i] < sa[i - 1]);
else rk[sa[i]] = ++p;
for(ll i: vec[u]) sec[L[i]].pb(i);
For(i, 1, 4 * n) tr.t[i] = (Data) {1, 0};
DFor(i, 2 * n + 1, 1) {
ll x = sa[i];
if(x <= n) {
for(ll j: sec[x]) {
assert(x + (1 << u) - 1 <= R[j] && R[j] <= x + (1 << u + 1) - 2);
ans[j] = (res[x] + tr.ask(1, 1, n, x + (1 << u) - 1, R[j])).sum;
} sec[x].clear();
if(x + (1 << u + 1) - 2 <= n)
res[x] = res[x] + tr.ask(1, 1, n, x + (1 << u) - 1, x + (1 << u + 1) - 2);
} else {
if(x == n + 1) continue;
x = 2 * n + 2 - x;
tr.modify(1, 1, n, x);
}
}
}
report();
return 0;
}

浙公网安备 33010602011771号