线段树WA求调,玄关!
查看原帖
线段树WA求调,玄关!
742017
zhangxiao666楼主2024/7/25 19:37
#include <bits/stdc++.h>
#define ls x << 1
#define rs x << 1 | 1
#define lson ls, l, mid
#define rson rs, mid + 1, r
using namespace std;
const int N = 1e5 + 10;
int n, m;
array<int, N> a;

struct stu
{
	int sum0, sum1;
	int max0, max1;
	int l0, l1, r0, r1;
	int tag1, tag2;
};

array<stu, N << 2> tr;
stu t;

void PushUp(int x)
{
	tr[x].sum0 = tr[ls].sum0 + tr[rs].sum0;
	tr[x].sum1 = tr[ls].sum1 + tr[rs].sum1;
	tr[x].max0 = max(max(tr[ls].max0, tr[rs].max0), tr[ls].r0 + tr[rs].l0);
	tr[x].max1 = max(max(tr[ls].max1, tr[rs].max1), tr[ls].r1 + tr[rs].l1);	
	tr[x].l0 = tr[ls].sum1 ? tr[ls].sum0 + tr[rs].l0 : tr[ls].l0;
	tr[x].l1 = tr[ls].sum0 ? tr[ls].sum1 + tr[rs].l1 : tr[ls].l1;	 
	tr[x].r0 = tr[rs].sum1 ? tr[rs].sum0 + tr[ls].r0 : tr[rs].r0;
	tr[x].r1 = tr[rs].sum0 ? tr[rs].sum1 + tr[ls].r1 : tr[rs].r1;	
}

stu Merge(stu aa, stu bb)
{
	stu xx;
	xx.sum0 = aa.sum0 + bb.sum0;
	xx.sum1 = aa.sum1 + bb.sum1;
	xx.max0 = max(max(aa.max0, bb.max0), aa.r0 + bb.l0);
	xx.max1 = max(max(aa.max1, bb.max1), aa.r1 + bb.l1);	
	xx.l0 = !aa.sum1 ? aa.sum0 + bb.l0 : aa.l0;
	xx.l1 = !aa.sum0 ? aa.sum1 + bb.l1 : aa.l1;	 
	xx.r0 = !bb.sum1 ? bb.sum0 + aa.r0 : bb.r0;
	xx.r1 = !bb.sum0 ? bb.sum1 + aa.r1 : bb.r1;	
	return xx;
}


void Build(int x, int l, int r)
{
	tr[x].tag1 = -1;
	if (l == r) 
	{
		if (a[l] == 0)
			tr[x].sum0 = tr[x].max0 = tr[x].l0 = tr[x].r0 = 1;
		else
			tr[x].sum1 = tr[x].max1 = tr[x].l1 = tr[x].r1 = 1;
		return;
	}
	int mid = l + r >> 1;
	Build(lson), Build(rson);
	PushUp(x);
}

void Change1(int x, int l, int r, int k)
{
	if (k == 0)
	{
		tr[x].sum0 = (r - l + 1), tr[x].sum1 = 0;
		tr[x].max0 = (r - l + 1), tr[x].max1 = 0;
		tr[x].l0 = tr[x].r0 = (r - l + 1);
		tr[x].l1 = tr[x].r1 = 0;
	}
	if (k == 1)
	{
		tr[x].sum1 = (r - l + 1), tr[x].sum0 = 0;
		tr[x].max1 = (r - l + 1), tr[x].max0 = 0;
		tr[x].l1 = tr[x].r1 = (r - l + 1);
		tr[x].l0 = tr[x].r0 = 0;	
	}
	tr[x].tag1 = k; tr[x].tag2 = 0;
}

void Change2(int x, int l, int r)
{
	swap(tr[x].sum0, tr[x].sum1);
	swap(tr[x].max0, tr[x].max1);
	swap(tr[x].l0, tr[x].l1);
	swap(tr[x].r0, tr[x].r1);
	if (tr[x].tag1 != -1) tr[x].tag1 ^= 1;
	else tr[x].tag2 ^= 1;
}

void PushDown(int x, int l, int r)
{
	int mid = l + r >> 1;
	if (tr[x].tag1 != -1)
	{
		Change1(lson, tr[x].tag1);
		Change1(rson, tr[x].tag1);
		tr[x].tag1 = -1;
	}
	if (tr[x].tag2)
	{
		Change2(lson), Change2(rson);
		tr[x].tag2 = 0;
	}
}

void Update(int x, int l, int r, int ql, int qr, int op)
{
	if (ql <= l && r <= qr)
	{
		if (op == 0) Change1(x, l, r, 0);
		if (op == 1) Change1(x, l, r, 1);
		if (op == 2) Change2(x, l, r);		
		return;
	}
	int mid = l + r >> 1; PushDown(x, l, r);
	if (ql <= mid) Update(lson, ql, qr, op);
	if (qr > mid) Update(rson, ql, qr, op);
	PushUp(x);
}

int Query1(int x, int l, int r, int ql, int qr)
{
	if (ql <= l && r <= qr) return tr[x].sum1;
	int mid = l + r >> 1, res = 0; PushDown(x, l, r);
	if (ql <= mid) res += Query1(lson, ql, qr);
	if (qr > mid) res += Query1(rson, ql, qr);
	return res;
}

stu Query2(int x, int l, int r, int ql, int qr)
{
	if (ql <= l && r <= qr) return tr[x];
	PushDown(x, l, r);
	int mid = l + r >> 1;
	if (qr <= mid) return Query2(lson, ql, qr);
	if (ql > mid) return Query2(rson, ql, qr);
	return Merge(Query2(lson, ql, qr), Query2(rson, ql, qr));
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i];
	Build(1, 1, n);
	while (m--)
	{
		int op, l, r;
		cin >> op >> l >> r;
		l++, r++;
		if (op < 3) 
			Update(1, 1, n, l, r, op);
		else
		{
			if (op == 3)
				cout << Query1(1, 1, n, l, r) << "\n";
			else 
			{
				cout << Query2(1, 1, n, l, r).max1 << "\n";
			}
		}
	}
	return 0;
}
2024/7/25 19:37
加载中...