【P2253】 好一个一中腰鼓!
Description
给定一个01子串和操作数,每次操作可以使一个元素0变为1, 1变为0,求区间最长连续相邻不相等的长度
Solution
对于最长连续不相等,我们可以用几个量来维护,为:
1 lf 从左边开始的最长连续相邻不相等最大长度
2 rf 从右边开始的最长连续相邻不相等最大长度
3 mf 内部的最长连续相邻不相等最大长度
所以,最长的长度为max(tr[1].lf, tr[1].rf, tr[1].mf),对于每一个变量我们可以这样维护
tr[x].lf = max(tr[x << 1].lf, tr[x << 1].lf + tr[x << 1 | 1].lf) 当然是有条件的base[mid] != base[mid + 1] && mid - l + 1 == tr[p].lf base表示为0还是为1,从右面同理
mf(p) = max(mf(p << 1), mf(p << 1 | 1));
if (base[mid] != base[mid + 1])
mf(p) = max(mf(p), lf(p << 1 | 1) + rf(p << 1));
Code
#include <bits/stdc++.h> const int N = 20010; using namespace std; int n, m; int turn[2] = {1, 0}, base[N]; struct emmm { int l, r, t, mf, lf, rf; #define l(x) tr[x].l #define r(x) tr[x].r #define mf(x) tr[x].mf #define lf(x) tr[x].lf #define rf(x) tr[x].rf } tr[N << 2]; void pushup(int p, int l, int r, int mid) { lf(p) = lf(p << 1); if (base[mid] != base[mid + 1] && mid - l + 1 == lf(p << 1)) lf(p) += lf(p << 1 | 1); rf(p) = rf(p << 1 | 1); if (base[mid] != base[mid + 1] && r - mid == rf(p << 1 | 1)) rf(p) += rf(p << 1); mf(p) = max(mf(p << 1), mf(p << 1 | 1)); if (base[mid] != base[mid + 1]) mf(p) = max(mf(p), lf(p << 1 | 1) + rf(p << 1)); return ; } void build(int p, int l, int r) { l(p) = l; r(p) = r; if (l == r) { mf(p) = lf(p) = rf(p) = 1; return ; } int mid = (l + r) >> 1; build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r); pushup(p, l, r, mid); } void update(int p, int l, int r, int x) { if (l > x || r < x) return ; if (l == x && r == x) { base[l] = turn[base[l]]; return ; } int mid = (l + r) >> 1; update(p << 1, l, mid, x); update(p << 1 | 1, mid + 1, r, x); pushup(p, l, r, mid); } int main() { scanf("%d%d", &n, &m); build(1, 1, n); for (int i = 1; i <= m; i++) { int x; scanf("%d", &x); update(1, 1, n, x); cout << max(lf(1), max(rf(1), mf(1))) << endl; } return 0; }