six_one @ 2023-10-02 22:39:17
眼睛看瞎了
// Problem: P2572 [SCOI2010] 序列操作
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2572
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define ll long long
#define inf 2000000000
using namespace std;
int read()
{
int num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
ll readll()
{
ll num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
/*
__int128 read128()
{
__int128 num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
void print(__int128 n)
{
if(n < 0)
{
putchar('-');
n *= -1;
}
if(n > 9) print(n / 10);
putchar(n % 10 + '0');
}
上面不用看*/
#define MAXn 100010
#define MAXm 100010
int n, m;
int a[MAXn];
struct SegmentTree
{
int l, r, ls, rs;
int num1, num0;
int lnum1, rnum1;
int lnum0, rnum0;
int max1, max0;
int flag0, flag1, flag2;
} tr[MAXn << 2];
void pushup(int x)
{
int ls = tr[x].ls, rs = tr[x].rs;
tr[x].num1 = tr[ls].num1 + tr[rs].num1;
tr[x].num0 = tr[ls].num0 + tr[rs].num0;
if(tr[ls].num0 == 0)
tr[x].lnum1 = tr[ls].num1 + tr[rs].lnum1;
else tr[x].lnum1 = tr[ls].lnum1;
if(tr[ls].num1 == 0)
tr[x].lnum0 = tr[ls].num0 + tr[rs].lnum0;
else tr[x].lnum0 = tr[ls].lnum0;
if(tr[rs].num0 == 0)
tr[x].rnum1 = tr[rs].num1 + tr[ls].rnum1;
else tr[x].rnum1 = tr[rs].rnum1;
if(tr[ls].num1 == 0)
tr[x].rnum0 = tr[rs].num0 + tr[ls].rnum0;
else tr[x].rnum0 = tr[rs].rnum0;
tr[x].max1 = max({tr[ls].max1, tr[rs].max1, tr[ls].rnum1 + tr[rs].lnum1});
tr[x].max0 = max({tr[ls].max0, tr[rs].max0, tr[ls].rnum0 + tr[rs].lnum0});
}
void pushdown(int id)
{
if(tr[id].flag0)
{
int x = tr[id].ls;
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
x = tr[id].rs;
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
tr[id].flag0 = tr[id].flag1 = tr[id].flag2 = 0;
}
else if(tr[id].flag1)
{
int x = tr[id].ls;
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
x = tr[x].rs;
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
tr[id].flag0 = tr[id].flag1 = tr[id].flag2 = 0;
}
if(tr[id].flag2)
{
int x = tr[id].ls;
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
x = tr[id].rs;
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
}
tr[id].flag0 = 0, tr[id].flag1 = 0, tr[id].flag2 = 0;
}
void build(int x, int L, int R)
{
tr[x].l = L, tr[x].r = R;
if(L == R)
{
if(a[L] == 1)
{
tr[x].num1 = 1;
tr[x].lnum1 = 1;
tr[x].rnum1 = 1;
tr[x].max1 = 1;
}
else
{
tr[x].num0 = 1;
tr[x].lnum0 = 1;
tr[x].rnum0 = 1;
tr[x].max0 = 1;
}
return;
}
int mid = (L + R) >> 1;
tr[x].ls = x << 1;
tr[x].rs = x << 1 | 1;
build(tr[x].ls, L, mid);
build(tr[x].rs, mid + 1, R);
pushup(x);
}
void change(int opt, int x, int L, int R)
{
if(tr[x].l >= L && tr[x].r <= R)
{
if(opt == 0)
{
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
}
else if(opt == 1)
{
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
}
else if(opt == 2)
{
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
}
return;
}
pushdown(x);
int mid = (tr[x].l + tr[x].r) >> 1;
if(L <= mid) change(opt, tr[x].ls, L, R);
if(R >= mid + 1) change(opt, tr[x].rs, L, R);
pushup(x);
}
SegmentTree ask(int opt, int x, int L, int R)
{
if(tr[x].l >= L && tr[x].r <= R)
return tr[x];
pushdown(x);
SegmentTree lres;
bool flag = 0;
int mid = (tr[x].l + tr[x].r) >> 1;
if(L <= mid) lres = ask(opt, tr[x].ls, L, R), flag = 1;
if(R >= mid + 1)
{
auto rres = ask(opt, tr[x].rs, L, R);
if(!flag)
{
return rres;
}
if(opt == 3)
{
lres.num1 += rres.num1;
return lres;
}
else
{
SegmentTree res;
res.num1 = lres.num1 + rres.num1;
res.num0 = lres.num0 + rres.num0;
if(lres.num0 == 0)
res.lnum1 = lres.num1 + rres.lnum1;
else res.lnum1 = lres.lnum1;
if(lres.num1 == 0)
res.lnum0 = lres.num0 + rres.lnum0;
else res.lnum0 = lres.lnum0;
if(rres.num0 == 0)
res.rnum1 = rres.num1 + lres.rnum1;
else res.rnum1 = rres.rnum1;
if(lres.num1 == 0)
res.rnum0 = rres.num0 + lres.rnum0;
else res.rnum0 = rres.rnum0;
res.max1 = max({lres.max1, rres.max1, res.lnum1, res.rnum1, lres.rnum1 + rres.lnum1});
res.max0 = max({lres.max0, rres.max0, res.lnum0, res.rnum0, lres.rnum0 + rres.lnum0});
res.l = lres.l, res.r = rres.r;
return res;
}
}
return lres;
}
void work()
{
n = read(), m = read();
for(int i = 1; i <= n; i++)
a[i] = read();
build(1, 1, n);
while(m--)
{
int opt = read(), l = read(), r = read();
l++, r++;
if(opt < 3) change(opt, 1, l, r);
else if(opt == 3) printf("%d\n", ask(opt, 1, l, r).num1);
else if(opt == 4) printf("%d\n", ask(opt, 1, l, r).max1);
}
return;
}
int main()
{
int T = 1;
while(T--)
{
work();
}
return 0;
}
by six_one @ 2023-10-02 22:40:16
救救孩子吧/dk
by six_one @ 2023-10-02 22:55:44
更改一处
// Problem: P2572 [SCOI2010] 序列操作
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2572
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define ll long long
#define inf 2000000000
using namespace std;
int read()
{
int num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
ll readll()
{
ll num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
/*
__int128 read128()
{
__int128 num = 0, w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
while(ch <= '9' && ch >= '0') { num = (num << 3) + (num << 1) + (ch - '0'); ch = getchar(); }
return num * w;
}
void print(__int128 n)
{
if(n < 0)
{
putchar('-');
n *= -1;
}
if(n > 9) print(n / 10);
putchar(n % 10 + '0');
}
*/
#define MAXn 100010
#define MAXm 100010
int n, m;
int a[MAXn];
struct SegmentTree
{
int l, r, ls, rs;
int num1, num0;
int lnum1, rnum1;
int lnum0, rnum0;
int max1, max0;
int flag0, flag1, flag2;
} tr[MAXn << 2];
void pushup(int x)
{
int ls = tr[x].ls, rs = tr[x].rs;
tr[x].num1 = tr[ls].num1 + tr[rs].num1;
tr[x].num0 = tr[ls].num0 + tr[rs].num0;
if(tr[ls].num0 == 0)
tr[x].lnum1 = tr[ls].num1 + tr[rs].lnum1;
else tr[x].lnum1 = tr[ls].lnum1;
if(tr[ls].num1 == 0)
tr[x].lnum0 = tr[ls].num0 + tr[rs].lnum0;
else tr[x].lnum0 = tr[ls].lnum0;
if(tr[rs].num0 == 0)
tr[x].rnum1 = tr[rs].num1 + tr[ls].rnum1;
else tr[x].rnum1 = tr[rs].rnum1;
if(tr[ls].num1 == 0)
tr[x].rnum0 = tr[rs].num0 + tr[ls].rnum0;
else tr[x].rnum0 = tr[rs].rnum0;
tr[x].max1 = max({tr[ls].max1, tr[rs].max1, tr[ls].rnum1 + tr[rs].lnum1});
tr[x].max0 = max({tr[ls].max0, tr[rs].max0, tr[ls].rnum0 + tr[rs].lnum0});
}
void pushdown(int id)
{
if(tr[id].flag0)
{
int x = tr[id].ls;
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
x = tr[id].rs;
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
}
else if(tr[id].flag1)
{
int x = tr[id].ls;
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
x = tr[x].rs;
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
}
if(tr[id].flag2)
{
int x = tr[id].ls;
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
x = tr[id].rs;
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
}
tr[id].flag0 = 0, tr[id].flag1 = 0, tr[id].flag2 = 0;
}
void build(int x, int L, int R)
{
tr[x].l = L, tr[x].r = R;
if(L == R)
{
if(a[L] == 1)
{
tr[x].num1 = 1;
tr[x].lnum1 = 1;
tr[x].rnum1 = 1;
tr[x].max1 = 1;
}
else
{
tr[x].num0 = 1;
tr[x].lnum0 = 1;
tr[x].rnum0 = 1;
tr[x].max0 = 1;
}
return;
}
int mid = (L + R) >> 1;
tr[x].ls = x << 1;
tr[x].rs = x << 1 | 1;
build(tr[x].ls, L, mid);
build(tr[x].rs, mid + 1, R);
pushup(x);
}
void change(int opt, int x, int L, int R)
{
if(tr[x].l >= L && tr[x].r <= R)
{
if(opt == 0)
{
tr[x].flag0 = 1;
tr[x].flag1 = 0, tr[x].flag2 = 0;
tr[x].num0 = tr[x].r - tr[x].l + 1;
tr[x].num1 = 0;
tr[x].lnum0 = tr[x].num0;
tr[x].rnum0 = tr[x].num0;
tr[x].lnum1 = 0;
tr[x].rnum1 = 0;
tr[x].max0 = tr[x].num0;
tr[x].max1 = 0;
}
else if(opt == 1)
{
tr[x].flag1 = 1;
tr[x].flag0 = 0, tr[x].flag2 = 0;
tr[x].num1 = tr[x].r - tr[x].l + 1;
tr[x].num0 = 0;
tr[x].lnum1 = tr[x].num1;
tr[x].rnum1 = tr[x].num1;
tr[x].lnum0 = 0;
tr[x].rnum0 = 0;
tr[x].max1 = tr[x].num1;
tr[x].max0 = 0;
}
else if(opt == 2)
{
tr[x].flag2 ^= 1;
swap(tr[x].num1, tr[x].num0);
swap(tr[x].max1, tr[x].max0);
swap(tr[x].lnum1, tr[x].lnum0);
swap(tr[x].rnum1, tr[x].rnum0);
}
return;
}
pushdown(x);
int mid = (tr[x].l + tr[x].r) >> 1;
if(L <= mid) change(opt, tr[x].ls, L, R);
if(R >= mid + 1) change(opt, tr[x].rs, L, R);
pushup(x);
}
SegmentTree ask(int opt, int x, int L, int R)
{
if(tr[x].l >= L && tr[x].r <= R)
return tr[x];
pushdown(x);
SegmentTree lres;
bool flag = 0;
int mid = (tr[x].l + tr[x].r) >> 1;
if(L <= mid) lres = ask(opt, tr[x].ls, L, R), flag = 1;
if(R >= mid + 1)
{
auto rres = ask(opt, tr[x].rs, L, R);
if(!flag)
{
return rres;
}
if(opt == 3)
{
lres.num1 += rres.num1;
return lres;
}
else
{
SegmentTree res;
res.num1 = lres.num1 + rres.num1;
res.num0 = lres.num0 + rres.num0;
if(lres.num0 == 0)
res.lnum1 = lres.num1 + rres.lnum1;
else res.lnum1 = lres.lnum1;
if(lres.num1 == 0)
res.lnum0 = lres.num0 + rres.lnum0;
else res.lnum0 = lres.lnum0;
if(rres.num0 == 0)
res.rnum1 = rres.num1 + lres.rnum1;
else res.rnum1 = rres.rnum1;
if(lres.num1 == 0)
res.rnum0 = rres.num0 + lres.rnum0;
else res.rnum0 = rres.rnum0;
res.max1 = max({lres.max1, rres.max1, res.lnum1, res.rnum1, lres.rnum1 + rres.lnum1});
res.max0 = max({lres.max0, rres.max0, res.lnum0, res.rnum0, lres.rnum0 + rres.lnum0});
res.l = lres.l, res.r = rres.r;
return res;
}
}
return lres;
}
void work()
{
n = read(), m = read();
for(int i = 1; i <= n; i++)
a[i] = read();
build(1, 1, n);
while(m--)
{
int opt = read(), l = read(), r = read();
l++, r++;
if(opt < 3) change(opt, 1, l, r);
else if(opt == 3) printf("%d\n", ask(opt, 1, l, r).num1);
else if(opt == 4) printf("%d\n", ask(opt, 1, l, r).max1);
}
return;
}
int main()
{
int T = 1;
while(T--)
{
work();
}
return 0;
}
by six_one @ 2023-10-03 18:56:35
已A,此贴终,l打成了r