xixike @ 2021-11-11 20:52:06
rt
#include <bits/stdc++.h>
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
inline int read(){
int x = 0;
char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x;
}
const int N = 1e5 + 10;
int n, m;
int a[N];
struct Seg_tree{
int sum, len, maxl0, maxr0, maxzd0, maxl1, maxr1, maxzd1, cov, rev;
void Swap(){
swap(maxl0, maxl1), swap(maxr0, maxr1), swap(maxzd0, maxzd1);
sum = len - sum;
}
}t[N << 2];
inline void pushup(int rt){
// cout << "ppushup" << endl;
// t[rt].len = t[ls].len + t[rs].len;
t[rt].sum = t[ls].sum + t[rs].sum;
t[rt].maxl1 = t[ls].maxl1;
t[rt].maxr1 = t[rs].maxr1;
if(t[ls].maxl1 == t[ls].len) t[rt].maxl1 = t[ls].len + t[rs].maxl1;
if(t[rs].maxr1 == t[rs].len) t[rt].maxr1 = t[rs].len + t[ls].maxr1;
t[rt].maxzd1 = max(t[ls].maxr1 + t[rs].maxl1, max(t[ls].maxzd1, t[rs].maxzd1));
t[rt].maxl0 = t[ls].maxl0;
t[rt].maxr0 = t[rs].maxr0;
if(t[ls].maxl0 == t[ls].len) t[rt].maxl0 = t[ls].len + t[rs].maxl0;
if(t[rs].maxr0 == t[rs].len) t[rt].maxr0 = t[rs].len + t[ls].maxr0;
t[rt].maxzd0 = max(t[ls].maxr0 + t[rs].maxl0, max(t[ls].maxzd0, t[rs].maxzd0));
}
inline void pushdown(int rt){
if(t[rt].cov != -1){
// cout << "pushdown " << rt << " " << t[rt].cov << endl;
t[ls].maxl1 = t[ls].maxr1 = t[ls].maxzd1 = t[ls].sum = t[ls].len * t[rt].cov;
t[rs].maxl1 = t[rs].maxr1 = t[rs].maxzd1 = t[rs].sum = t[rs].len * t[rt].cov;
t[ls].maxl0 = t[ls].maxr0 = t[ls].maxzd0 = t[ls].len * (t[rt].cov ^ 1);
t[rs].maxl0 = t[rs].maxr0 = t[rs].maxzd0 = t[rs].len * (t[rt].cov ^ 1);
// cout << t[rt].sum << " " << t[ls].sum << " " << t[rs].sum << endl;
t[ls].cov = t[rs].cov = t[rt].cov;
t[ls].rev = t[rs].rev = 0;
t[rt].cov = -1;
}
if(t[rt].rev){
// cout << "pushdown " << endl;
t[ls].Swap(), t[rs].Swap();
t[ls].rev ^= 1, t[rs].rev ^= 1;
t[rt].rev = 0;
}
}
inline void build(int l, int r, int rt){
t[rt].cov = -1, t[rt].len = r - l + 1;
if(l == r){
t[rt].maxl1 = t[rt].maxr1 = t[rt].maxzd1 = t[rt].sum = a[l];
t[rt].maxl0 = t[rt].maxr0 = t[rt].maxzd0 = a[l] ^ 1;
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
pushup(rt);
}
inline void update_cov(int L, int R, int k, int l, int r, int rt){
if(L <= l && r <= R){
// cout << "cover " << rt << endl;
t[rt].maxl1 = t[rt].maxr1 = t[rt].maxzd1 = t[rt].sum = t[rt].len * k;
t[rt].maxl0 = t[rt].maxr0 = t[rt].maxzd0 = t[rt].len * (k ^ 1);
t[rt].cov = k;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) update_cov(L, R, k, l, mid, ls);
if(R > mid) update_cov(L, R, k, mid + 1, r, rs);
pushup(rt);
}
inline void update_rev(int L, int R, int l, int r, int rt){
if(L <= l && r <= R){
// cout << t[rt].sum << endl;
// cout << "rttt " << rt << " " << l << " " << r << " " << t[rt].maxzd1 << endl;
t[rt].Swap();
t[rt].rev ^= 1;
// cout << t[rt].maxzd1 << endl;
return;
}
pushdown(rt);
// cout << rt << " " << l << " " << r << " maxzd1 ";
// for(int i = 1; i <= (n << 2); ++i)
// cout << t[i].maxzd1 << " ";
// cout << endl;
int mid = (l + r) >> 1;
if(L <= mid) update_rev(L, R, l, mid, ls);
if(R > mid) update_rev(L, R, mid + 1, r, rs);
pushup(rt);
}
inline int query_sum(int L, int R, int l, int r, int rt){
if(L <= l && r <= R) return t[rt].sum;
pushdown(rt);
int mid = (l + r) >> 1, res = 0;
if(L <= mid) res += query_sum(L, R, l, mid, ls);
if(R > mid) res += query_sum(L, R, mid + 1, r, rs);
return res;
}
inline int query_len(int L, int R, int l, int r, int rt){
if(L <= l && r <= R) return t[rt].maxzd1;
pushdown(rt);
int mid = (l + r) >> 1, res = min(t[ls].maxr1, mid - L + 1) + min(t[rs].maxl1, R - mid);
if(L <= mid) res = max(res, query_len(L, R, l, mid, ls));
if(R > mid) res = max(res, query_len(L, R, mid + 1, r, rs));
return res;
}
int main(){
freopen("P2572.in", "r", stdin);
freopen("P2572.out", "w", stdout);
n = read(), m = read();
for(int i = 1; i <= n; ++i)
a[i] = read();
build(1, n, 1);
// for(int i = 1; i <= (n << 2); ++i)
// cout << t[i].sum << " ";
// cout << endl;
// printf("%d %d\n", query_sum(1, 5, 1, n, 1), query_len(5, 9, 1, n, 1));
for(int i = 1; i <= m; ++i){
int op = read(), l = read() + 1, r = read() + 1;
if(!op) update_cov(l, r, 0, 1, n, 1);
else if(op == 1) update_cov(l, r, 1, 1, n, 1);
else if(op == 2) update_rev(l, r, 1, n, 1);
else if(op == 3) printf("%d\n", query_sum(l, r, 1, n, 1));
else printf("%d\n", query_len(l, r, 1, n, 1));
// cout << "i " << i << endl;
// for(int j = 1; j <= (n << 2); ++j)
// cout << t[j].maxzd1 << " ";
// cout << endl << endl << endl;
}
return 0;
}
by xixike @ 2021-11-11 20:59:05
虽然代码有一点点长
by fzj2007 @ 2021-11-11 21:02:08
sto @xixike orz
by xixike @ 2021-11-11 21:04:54
@fzj2007 fls 快帮我看看!/kk
by xixike @ 2021-11-11 21:15:20
此贴终,update_cov
函数中没有清空反转标记。
by LawrenceSivan @ 2021-11-11 21:44:11
@xixike 草,我刚打开准备看
by LawrenceSivan @ 2021-11-11 21:44:29
@xixike Orz debug 的神
by xixike @ 2021-11-11 22:02:26
@LawrenceSivan 其实已经看了好长时间了qwq