求助:不开O2 AC,开O2 20pts
查看原帖
求助:不开O2 AC,开O2 20pts
325319
ohnmachesya楼主2022/11/11 11:11

代码:

#include <bits/stdc++.h>
using namespace std;

#define int long long

#define MAXN 100005
#define pushup(now) tree[now] = tree[now<<1] + tree[now<<1|1]

struct Tag {
	int g1, g2;
	Tag(int G1 = -1, int G2 = 0): g1(G1), g2(G2) {} //g1: 平推  g2:取反

	Tag operator + (Tag y) {
		if (g1 == -1 && g2 == 0) return y;
		if (y.g1 == -1 && y.g2 == 0) return *this;

		if (y.g1 != -1 && y.g2 == 0) return y;
		if (y.g1 == -1) {
			//g1 == 0 && g2 == 0 : 0
			//g1 == 1 && g2 == 0 : 1
			//g1 == 0 && g2 == 1 : 1
			//g1 == 1 && g2 == 1 : 1
			g2 ^= y.g2;
			return *this;
		}
	}
};

struct node {
	int l, r, len, sum0, sum1, fi0, fi1, la0, la1, len0, len1;
	Tag tag;
	node operator + (node x) {
		node t;
		t.l = l;
		t.r = x.r;
		t.len = len + x.len;
		t.sum0 = sum0 + x.sum0;
		t.sum1 = sum1 + x.sum1;

		if (len == fi0) t.fi0 = fi0 + x.fi0;
		else t.fi0 = fi0;

		if (len == fi1) t.fi1 = fi1 + x.fi1;
		else t.fi1 = fi1;

		if (x.la0 == x.len) t.la0 = la0 + x.len;
		else t.la0 = x.la0;

		if (x.la1 == x.len) t.la1 = la1 + x.len;
		else t.la1 = x.la1;

		t.len0 = max(len0, max(x.len0, (la0 + x.fi0)));
		t.len1 = max(len1, max(x.len1, (la1 + x.fi1)));

		t.tag = Tag();

		return t;
	}

	void operator += (Tag x) {
		if (x.g1 == 0) {
			fi0 = la0 = len0 = sum0 = len;
			fi1 = la1 = len1 = sum1 = 0;
		}
		if (x.g1 == 1) {
			fi0 = la0 = len0 = sum0 = 0;
			fi1 = la1 = len1 = sum1 = len;
		}
		if (x.g2 == 1) {
			swap(fi0, fi1);
			swap(la0, la1);
			swap(len0, len1);
			swap(sum0, sum1);
		}

		tag = tag + x;
	}
} tree[MAXN << 2];

void pushdown(int now) {
	tree[now << 1] += tree[now].tag;
	tree[now << 1 | 1] += tree[now].tag;

	tree[now].tag = Tag();
}

int arr[MAXN];

void build(int l, int r, int now) {
	if (l == r) {
		tree[now].l = l;
		tree[now].r = r;
		tree[now].len = 1;
		if (arr[l] == 1) {
			tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 0;
			tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 1;
		} else {
			tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 1;
			tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 0;
		}

		tree[now].tag = Tag();

		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, now << 1);
	build(mid + 1, r, now << 1 | 1);

	pushup(now);
}

void modify(int l, int r, Tag tag, int now) {
	if (tree[now].l != tree[now].r) pushdown(now);

	if (l <= tree[now].l && tree[now].r <= r) {
		tree[now] += tag;
		return;
	}

	int mid = (tree[now].l + tree[now].r) >> 1;
	if (l <= mid) modify(l, r, tag, now << 1);
	if (r > mid) modify(l, r, tag, now << 1 | 1);

	pushup(now);
}

node query(int l, int r, int now) {
	if (tree[now].l != tree[now].r) pushdown(now);

	if (l <= tree[now].l && tree[now].r <= r) return tree[now];

	int mid = (tree[now].l + tree[now].r) >> 1;
	if (l <= mid && r > mid) return query(l, r, now << 1) + query(l, r, now << 1 | 1);
	if (l <= mid) return query(l, r, now << 1);
	if (r > mid) return query(l, r, now << 1 | 1);
}

signed main() {
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> arr[i];
	build(1, n, 1);
	while (m--) {
		int opt, l, r;
		cin >> opt >> l >> r;
		if (opt == 0) modify(l + 1, r + 1, {0, 0}, 1);
		if (opt == 1) modify(l + 1, r + 1, {1, 0}, 1);
		if (opt == 2) modify(l + 1, r + 1, {-1, 1}, 1);
		if (opt == 3) cout << query(l + 1, r + 1, 1).sum1 << endl;
		if (opt == 4) cout << query(l + 1, r + 1, 1).len1 << endl;
	}
	return 0;
}
2022/11/11 11:11
加载中...