QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#864727 | #5037. 回文 | Felix72 | 0 | 0ms | 0kb | C++14 | 11.3kb | 2025-01-20 22:20:41 | 2025-01-20 22:20:42 |
Judging History
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 = 10000000000000061;
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] = ((__int128)val[0] * P + s[j]) % mod;
hsh[0][j - l + 1] = val[0];
}
for(int j = r; j >= l; --j)
{
val[1] = ((__int128)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] = ((__int128)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] = ((__int128)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] - (__int128)part[id].hsh[0][l - 1] * pw[r - l + 1] % mod + mod) % mod;
else return (part[id].hsh[1][l] - (__int128)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 = (__int128)res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
res = (res + (pre[bid[r] - 1] - (__int128)pre[bid[l]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
}
res = (__int128)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 = (__int128)res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
res = (res + (suf[bid[l] + 1] - (__int128)suf[bid[r]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
}
res = (__int128)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;
for(int i = l; i <= r; ++i) if(i <= r - (i - l)) swap(s[i], s[r - (i - l)]);
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);
for(int i = l; i <= r; ++i) if(i <= r - (i - l)) swap(s[i], s[r - (i - l)]);
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; 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
Memory Limit Exceeded
Test #1:
score: 0
Memory Limit Exceeded
input:
aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...
output:
result:
Subtask #2:
score: 0
Memory Limit Exceeded
Test #15:
score: 0
Memory Limit Exceeded
input:
aabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbbaaabbaabbbbaabbaaabbbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbaaabaaaaaabaaabbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabb...
output:
41 45 153 119 60 167 50 166 118 204 148 143 29 70 118 123 159 10 105 307 101 74 37 362 78 182 55 34 84 263 72 112 79 192 152 153 155 50 130 137 142 26 308 9 12 258 257 137 356 49 115 332 17 126 19 35 117 157 40 93 285 90 351 168 61 150 46 181 102 283 166 24 84 177 32 123 64 125 282 22 81 213 120 144...
result:
Subtask #3:
score: 0
Time Limit Exceeded
Test #21:
score: 0
Time Limit Exceeded
input:
abbaaaabbabaaaaaabaabbaabbababbaaabbabbbabaabaabaaaaabaabbbbabbabbabbbababbbababababbbbabaabbaaababbbbbababbbbaabbbaaabaababababaabbbbbbaababaabbaaabaabbaaababbabbabbbbaaaaabaaabbbabbbbbbabbbabbabaabbbbbbbaaaabbaaaababbbaaaaaaababaabbbbaaabaaabbaabbbbbbababbaabbaaabbabbbbbabaababbaabaaaabbbbabababba...
output:
result:
Subtask #4:
score: 0
Time Limit Exceeded
Test #27:
score: 0
Time Limit Exceeded
input:
babbaaabbbbbbbabbbababaabbbbbababababbaabaabbbbbbabbbbbbbbbbababbbbabbaabbbaabaabbabbbaabbabbbabbababaababbbabbbbaabbabbabbaaaabbbaaabbbbaabbaaaaaaabbbabbbaaabaababaaabaaaabaaaababaaaaababaaaabaabbaaaabbbabbaabaabbbabbbbbaaabaababbbaaaaabbbbaaabbbbaabbabbbbabbbabbaaaaabaabaaaabbbabbbbbaabbbbabbbbaab...
output:
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 ...
result:
Subtask #5:
score: 0
Skipped
Dependency #1:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
0%