线段树的题, 自己写了好久都没写出来, 就找了一个大神的模板。
#include <bits/stdc++.h>
const int N = 1e5+10;
typedef long long ll;
char s[N];
int n, q;
struct SegTree {
struct Node {
int l, r;
int lenl, lenr;
int maxlen, ld, rd;
} tr[N<<2];
void pushup(Node &root, Node &left, Node &right) {
if(left.maxlen>=right.maxlen) {
root.maxlen = left.maxlen;
root.ld = left.ld, root.rd = left.rd;
}
else {
root.maxlen = right.maxlen;
root.ld = right.ld, root.rd = right.rd;
}
if(s[left.r]==s[right.l]) {
if(left.lenr+right.lenl>root.maxlen||((left.lenr+right.lenl==root.maxlen)&&left.r-left.lenr+1<=root.ld)) {
root.maxlen = left.lenr+right.lenl;
root.ld = left.r-left.lenr+1;
root.rd = right.l+right.lenl-1;
}
}
if(left.lenl==(left.r-left.l+1)&&s[left.l]==s[right.l]) {
root.lenl = left.lenl+right.lenl;
}
else {
root.lenl = left.lenl;
}
if(right.lenr==(right.r-right.l+1)&&s[right.r]==s[left.r]) {
root.lenr = right.lenr+left.lenr;
}
else {
root.lenr = right.lenr;
}
if(root.lenl>=root.maxlen) {
root.maxlen = root.lenl;
root.ld = left.l, root.rd = left.l+root.lenl-1;
}
if(root.lenr>root.maxlen) {
root.maxlen = root.lenr;
root.rd = right.r, root.ld = right.r-root.lenr+1;
}
}
void pushup(int u) {
Node &root = tr[u], &left = tr[u<<1], &right = tr[u<<1|1];
pushup(root,left,right);
}
void build(int u, int l, int r) {
tr[u] = {l,r,1,1,1,l,r};
if(l==r) return ;
int mid = (l+r)>>1;
build(u<<1,l,mid), build(u<<1|1,mid+1,r);
pushup(u);
}
Node query(int u, int l, int r) {
if(l<=tr[u].l&&tr[u].r<=r) return tr[u];
int mid = (tr[u].l+tr[u].r)>>1;
Node res = {tr[u].l,tr[u].r,0,0,0,0,0}, left = {tr[u].l,mid,0,0,0,0,0}, right = {mid+1,tr[u].r,0,0,0,0,0};
if(l<=mid) left = query(u<<1,l,r);
if(r>mid) right = query(u<<1|1,l,r);
// if(r<=mid) return left;
// if(l>mid) return right;
pushup(res,left,right);
return res;
}
void modify(int u, int x) {
if(tr[u].l==tr[u].r) {
return ;
}
int mid = (tr[u].l+tr[u].r)>>1;
if(x<=mid) modify(u<<1,x);
if(x>mid) modify(u<<1|1,x);
pushup(u);
}
} T;
void solve()
{
std::cin >> n >> q >> (s+1);
T.build(1,1,n);
while(q --) {
int op, l, r, x;
char c;
std::cin >> op;
if(op==1) {
std::cin >> l >> r;
auto res = T.query(1,l,r);
std::cout << res.ld << " " << res.rd << "\n";
}
else {
std::cin >> x >> c;
s[x] = c;
T.modify(1,x);
}
}
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int t = 1;
while(t --)
solve();
return 0;
}