QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#864758 | #5037. 回文 | Felix72 | 0 | 0ms | 0kb | C++14 | 11.0kb | 2025-01-20 23:43:40 | 2025-01-20 23:43:40 |
answer
/* Good Game, Well Play. */
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-(x)))
using namespace std;
const int N = 200010, P = 131;
const long long mod = 1000000123;
int n, m, B; string s; long long pw[N];
bool Entag = false; int Enl, Enr;
struct Blocks
{
int bid[N]; long long pre[N], suf[N];
struct Part
{
int l, r; long long val[2];
vector < long long > hsh[2];
inline void rebuild()
{
for(int op = 0; op <= 1; ++op)
val[op] = 0, hsh[op].resize(r - l + 3);
for(int j = l; j <= r; ++j)
{
val[0] = (val[0] * P + s[j]) % mod;
hsh[0][j - l + 1] = val[0];
}
for(int j = r; j >= l; --j)
{
val[1] = (val[1] * P + s[j]) % mod;
hsh[1][j - l + 1] = val[1];
}
}
}; Part part[N];
inline void init_sum()
{
for(int i = 1; i <= bid[n]; ++i)
pre[i] = (pre[i - 1] * pw[part[i].r - part[i].l + 1] + part[i].val[0]) % mod;
for(int i = bid[n]; i >= 1; --i)
suf[i] = (suf[i + 1] * pw[part[i].r - part[i].l + 1] + part[i].val[1]) % mod;
}
inline long long in_query(int op, int id, int l, int r)
{
if(op == 0) return (part[id].hsh[0][r] - part[id].hsh[0][l - 1] * pw[r - l + 1] % mod + mod) % mod;
else return (part[id].hsh[1][l] - part[id].hsh[1][r + 1] * pw[r - l + 1] % mod + mod) % mod;
}
inline void _setup()
{
B = sqrt(n);
for(int i = 1; i <= n; ++i) bid[i] = (i - 1) / B + 1;
for(int i = 1; i <= bid[n]; ++i)
{
part[i].l = B * (i - 1) + 1;
part[i].r = min(B * i, n);
part[i].rebuild();
}
init_sum();
}
inline void _modify(int p)
{
part[bid[p]].rebuild();
init_sum();
}
inline long long _query(int op, int l, int r)
{
if(Entag)
{
op ^= 1; swap(l, r);
l = Enr - (l - Enl);
r = Enr - (r - Enl);
}
if(l > r) return 0;
if(bid[l] == bid[r]) return in_query(op, bid[l], l - part[bid[l]].l + 1, r - part[bid[l]].l + 1);
else
{
long long res = 0;
if(op == 0)
{
res = in_query(0, bid[l], l - part[bid[l]].l + 1, part[bid[l]].r - part[bid[l]].l + 1);
if(bid[l] + 1 < bid[r])
{
res = res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
res = (res + (pre[bid[r] - 1] - pre[bid[l]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
}
res = res * pw[r - part[bid[r]].l + 1] % mod;
res = (res + in_query(0, bid[r], 1, r - part[bid[r]].l + 1)) % mod;
}
else
{
res = in_query(1, bid[r], 1, r - part[bid[r]].l + 1);
if(bid[l] + 1 < bid[r])
{
res = res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
res = (res + (suf[bid[l] + 1] - suf[bid[r]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
}
res = res * pw[part[bid[l]].r - l + 1] % mod;
res = (res + in_query(1, bid[l], l - part[bid[l]].l + 1, part[bid[l]].r - part[bid[l]].l + 1)) % mod;
}
return res;
}
}
}; Blocks blocks;
struct Seq
{
int x, d, l;
bool operator < (const Seq &w) const {return x < w.x;}
bool operator > (const Seq &w) const {return x > w.x;}
};
inline vector < Seq > compress(vector < Seq > vec)
{
sort(vec.begin(), vec.end());
// cerr << "+++++++++++++++++++++++++++++++++++++++\n";
// for(Seq sq : vec) cerr << "org " << sq.x << " " << sq.d << " " << sq.l << '\n';
vector < Seq > res;
for(Seq sq : vec)
{
if(!res.empty())
{
if(res.back().l == 1 && sq.l == 1)
res.back().d = sq.x - res.back().x, ++res.back().l;
else if(res.back().l == 1 && sq.x - res.back().x == sq.d)
res.back().d = sq.d, res.back().l += sq.l;
else if(sq.l == 1 && sq.x - (res.back().x + res.back().d * (res.back().l - 1)) == res.back().d)
++res.back().l;
else if(res.back().l > 1 && sq.l > 1 && res.back().d == sq.d && sq.x - (res.back().x + res.back().d * (res.back().l - 1)) == res.back().d)
res.back().l += sq.l;
else res.push_back(sq);
}
else res.push_back(sq);
}
// for(Seq sq : res) cerr << "final " << sq.x << " " << sq.d << " " << sq.l << '\n';
return res;
}
struct Data
{
int l, r;
vector < Seq > pr, su;
inline void unit(int p)
{
l = r = p;
pr.clear(); su.clear();
pr.push_back({1, 1, 1});
su.push_back({1, 1, 1});
}
inline void reset(int ln, int rn)
{l = ln, r = rn, pr.clear(), su.clear();}
inline void debug()
{
cerr << "pr : ";
for(Seq sq : pr) cerr << "(" << sq.x << "," << sq.d << "," << sq.l << ") ";
cerr << '\n';
cerr << "su : ";
for(Seq sq : su) cerr << "(" << sq.x << "," << sq.d << "," << sq.l << ") ";
cerr << '\n';
}
};
const bool Enop[5] = {false, true, true, true, true};
inline void work(Data u, Data v, int l, int mid, int r, Data &res)
{
// cerr << "work " << l << " " << mid << " " << r << '\n';
// for(int i = l; i <= r; ++i) cerr << s[i]; cerr << '\n';
// u.debug(); cerr << '\n'; v.debug();
// Case I
if(Enop[1])
{
res.su = v.su;
}
// Case II
if(Enop[2])
{
for(Seq sq : v.pr)
{
// cerr << "! " << sq.x << " " << sq.d << " " << sq.l << '\n';
if(sq.l == 1)
{
if(sq.x != r - mid && l <= mid - (r - mid - sq.x) + 1 && blocks._query(0, mid + sq.x + 1, r) == blocks._query(1, mid - (r - mid - sq.x) + 1, mid))
res.su.push_back({sq.x + 2 * (r - mid - sq.x), 1, 1});
}
else
{
int ex = r - mid - (sq.x + sq.d * (sq.l - 1));
if(!ex || blocks._query(0, mid + sq.x + sq.d * (sq.l - 1) + 1, r) == blocks._query(0, mid + sq.x + 1, mid + sq.x + (r - mid - sq.x - sq.d * (sq.l - 1))))
{
int head = (ex ? 0 : 1), tail = sq.l - 1, lim = -1;
while(head <= tail)
{
int md = (head + tail) >> 1;
if(l <= mid - (md * sq.d + ex) + 1 && blocks._query(0, r - (md * sq.d + ex) + 1, r) == blocks._query(1, mid - (md * sq.d + ex) + 1, mid))
lim = md, head = md + 1;
else tail = md - 1;
}
if(lim != -1)
{
// cerr << "lim " << lim << '\n';
if(ex) res.su.push_back({(r - mid) + ex, sq.d, lim + 1});
else res.su.push_back({(r - mid) + sq.d, sq.d, lim});
}
}
else
{
int head = 1, tail = sq.l - 1, lim = 0;
while(head <= tail)
{
int md = (head + tail) >> 1;
if(l <= mid - md * sq.d + 1 && blocks._query(1, mid - md * sq.d + 1, mid) == blocks._query(0, mid + sq.x + 1, mid + sq.x + md * sq.d))
lim = md, head = md + 1;
else tail = md - 1;
}
if(l <= mid - lim * sq.d - ex + 1 && blocks._query(1, mid - lim * sq.d - ex + 1, mid) == blocks._query(0, r - (lim * sq.d + ex) + 1, r))
res.su.push_back({r - mid + lim * sq.d + ex, 1, 1});
}
}
}
}
// Case III
if(Enop[3])
{
if(r - mid <= mid - l + 1)
{
if(blocks._query(0, mid + 1, r) == blocks._query(1, mid - (r - mid) + 1, mid))
res.su.push_back({2 * (r - mid), 1, 1});
}
}
// Case IV
if(Enop[4])
{
for(Seq sq : u.su)
{
if(sq.l == 1)
{
if(l <= mid - sq.x - (r - mid) + 1 && blocks._query(0, mid + 1, r) == blocks._query(1, mid - sq.x - (r - mid) + 1, mid - sq.x))
res.su.push_back({sq.x + 2 * (r - mid), 1, 1});
}
else
{
if(mid - sq.x - (r - mid) + 1 < l) continue;
int head = 1, tail = (sq.l - 1) * sq.d, lim = 0;
while(head <= tail)
{
int md = (head + tail) >> 1;
if(mid + md <= r && blocks._query(0, mid + 1, mid + md) == blocks._query(1, mid - sq.x - md + 1, mid - sq.x))
lim = md, head = md + 1;
else tail = md - 1;
}
if(lim == r - mid)
{
head = 0, tail = sq.l - 1, lim = -1;
while(head <= tail)
{
int md = (head + tail) >> 1;
if(l <= mid - sq.x - md * sq.d - (r - mid) + 1 && blocks._query(0, mid - sq.x - md * sq.d - (r - mid) + 1, mid - sq.x - md * sq.d) == blocks._query(1, mid + 1, r))
lim = md, head = md + 1;
else tail = md - 1;
}
if(lim != -1) res.su.push_back({sq.x + 2 * (r - mid), sq.d, lim + 1});
}
else
{
head = 0, tail = sq.l - 1, lim = 0;
while(head <= tail)
{
int md = (head + tail) >> 1;
if(mid + md * sq.d <= r && blocks._query(0, mid - sq.x - sq.d * md + 1, mid - sq.x) == blocks._query(1, mid + 1, mid + sq.d * md))
lim = md, head = md + 1;
else tail = md - 1;
}
lim *= sq.d;
if(l <= mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1)
{
if(blocks._query(0, mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1, r) == blocks._query(1, mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1, r))
res.su.push_back({sq.x + (sq.d * (sq.l - 1) - lim) + (r - mid) * 2, 1, 1});
}
}
}
}
}
}
Data operator + (Data u, Data v)
{
int l = u.l, mid = u.r, r = v.r;
Data res; res.reset(l, r);
// -------------- Suffix --------------
Entag = false; work(u, v, l, mid, r, res);
// -------------- Prefix --------------
Entag = true; Enl = l, Enr = r;
swap(u, v);
swap(res.pr, res.su), swap(u.pr, u.su), swap(v.pr, v.su);
work(u, v, l, r - (mid - l) - 1, r, res);
swap(res.pr, res.su), swap(u.pr, u.su), swap(v.pr, v.su);
swap(u, v);
res.pr = compress(res.pr); res.su = compress(res.su);
return res;
}
struct SegTree
{
int rt, idx;
struct SGT
{
int ls, rs; Data data;
#define ls(x) tree[x].ls
#define rs(x) tree[x].rs
#define data(x) tree[x].data
} tree[N * 2];
inline void pushup(int now)
{data(now) = data(ls(now)) + data(rs(now));}
inline void build(int &now, int l, int r)
{
now = ++idx;
if(l == r) {data(now).unit(l); return ;}
int mid = (l + r) >> 1;
build(ls(now), l, mid), build(rs(now), mid + 1, r);
pushup(now);
// cerr << "build " << l << " " << r << " ++++++++++++++++++++++++++++++++++++++\n";
// data(now).debug();
}
inline void modify(int now, int l, int r, int pos)
{
if(l == r) return ;
int mid = (l + r) >> 1;
if(pos <= mid) modify(ls(now), l, mid, pos);
else modify(rs(now), mid + 1, r, pos);
pushup(now);
}
inline Data query(int now, int l, int r, int L, int R)
{
if(L <= l && r <= R) return data(now);
int mid = (l + r) >> 1;
Data res;
if(R <= mid) res = query(ls(now), l, mid, L, R);
else if(mid < L) res = query(rs(now), mid + 1, r, L, R);
else res = (query(ls(now), l, mid, L, R) + query(rs(now), mid + 1, r, L, R));
// cerr << "query " << l << " " << r << " ++++++++++++++++++++\n";
// res.debug();
return res;
}
inline void _init() {build(rt, 1, n);}
inline void _modify(int p) {modify(rt, 1, n, p);}
inline Data _query(int l, int r) {return query(rt, 1, n, l, r);}
}; SegTree sgt;
int main()
{
freopen("text.in", "r", stdin);
freopen("prog.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> s; n = s.length(); s = ' ' + s;
pw[0] = 1; for(int i = 1; i <= n; ++i) pw[i] = (__int128)pw[i - 1] * P % mod;
blocks._setup(); sgt._init();
cin >> m;
for(int i = 1, lst = 0; i <= m; ++i)
{
int opt, l, r, p; char c; cin >> opt;
if(opt == 1)
{
cin >> p >> c;
// p ^= lst;
s[p] = c; blocks._modify(p), sgt._modify(p);
}
else
{
cin >> l >> r;
// l ^= lst, r ^= lst;
lst = 0; Data dt = sgt._query(l, r);
for(Seq sq : dt.su) lst += sq.l;
cout << lst << '\n';
}
}
return 0;
}
/*
abbaaabaac
1
2 1 7
*/
详细
Subtask #1:
score: 0
Dangerous Syscalls
Test #1:
score: 0
Dangerous Syscalls
input:
aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...
output:
result:
Subtask #2:
score: 0
Dangerous Syscalls
Test #15:
score: 0
Dangerous Syscalls
input:
aabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbbaaabbaabbbbaabbaaabbbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbaaabaaaaaabaaabbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabb...
output:
result:
Subtask #3:
score: 0
Dangerous Syscalls
Test #21:
score: 0
Dangerous Syscalls
input:
abbaaaabbabaaaaaabaabbaabbababbaaabbabbbabaabaabaaaaabaabbbbabbabbabbbababbbababababbbbabaabbaaababbbbbababbbbaabbbaaabaababababaabbbbbbaababaabbaaabaabbaaababbabbabbbbaaaaabaaabbbabbbbbbabbbabbabaabbbbbbbaaaabbaaaababbbaaaaaaababaabbbbaaabaaabbaabbbbbbababbaabbaaabbabbbbbabaababbaabaaaabbbbabababba...
output:
result:
Subtask #4:
score: 0
Dangerous Syscalls
Test #27:
score: 0
Dangerous Syscalls
input:
babbaaabbbbbbbabbbababaabbbbbababababbaabaabbbbbbabbbbbbbbbbababbbbabbaabbbaabaabbabbbaabbabbbabbababaababbbabbbbaabbabbabbaaaabbbaaabbbbaabbaaaaaaabbbabbbaaabaababaaabaaaabaaaababaaaaababaaaabaabbaaaabbbabbaabaabbbabbbbbaaabaababbbaaaaabbbbaaabbbbaabbabbbbabbbabbaaaaabaabaaaabbbabbbbbaabbbbabbbbaab...
output:
result:
Subtask #5:
score: 0
Skipped
Dependency #1:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
0%