疑似线段树pushdown不及时,求调
查看原帖
疑似线段树pushdown不及时,求调
743373
Vitamin_B楼主2024/8/17 00:32

P5568

初步判定为pushdown不及时/pushdown写炸一类的事。

//# pragma GCC optimize("Ofast,no-stack-protector")
//
//# pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

# include <bits/stdc++.h>

//# define I return
//
//# define AK 0
//
//# define IOI ;

using namespace std;

typedef long long ll;

typedef pair <int, int> pii;

int n = 131075, l, r, tr[524305], all[524305], lst;

char op, opl, opr;

bool flag;

bitset <524305> swp, ans;

void build (const int x, const int l, const int r) {

	all[x] = -1;

	if (l == r)
		return ;

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	build (left, l, mid), build (right, mid + 1, r);

	return ;

}

void pushdown (const int x, const int left, const int right, const int l, const int r, const int mid) {

	if (! all[x]) {

		tr[left] = tr[right] = 0;

		swp[left] = swp[right] = 0;

		all[left] = all[right] = 0;

		all[x] = -1;

	} else if (~ all[x]) {

		tr[left] = mid - l + 1, tr[right] = r - mid;

		swp[left] = swp[right] = 0;

		all[left] = all[right] = 1;

		all[x] = -1;

	}
	
	if (swp[x]) {

		tr[left] = mid - l + 1 - tr[left], tr[right] = r - mid - tr[right];

		if (~ all[left])
			all[left] = ! all[left];
		else
			swp[left] = ! swp[left];

		if (~ all[right])
			all[right] = ! all[right];
		else
			swp[right] = ! swp[right];

		swp[x] = 0;

	}

	return ;

}

void U (const int x, const int l, const int r, const int L, const int R) {
//	if (r <= 10) cerr << x << ':' << l << '~' << r << ':' << L << '~' << R << ':' << tr[x] << '\n';
	if (l == L && r == R) {

		tr[x] = r - l + 1;

		all[x] = 1, swp[x] = 0;

		return ;

	}

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	if (R <= mid)
		U (left, l, mid, L, R);
	else if (L > mid)
		U (right, mid + 1, r, L, R);
	else
		U (left, l, mid, L, mid), U (right, mid + 1, r, mid + 1, R);

	tr[x] = tr[left] + tr[right];

	return ;

}

void I (const int x, const int l, const int r, const int L, const int R) {

	if (l == L && r == R)
		return ;

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	if (R <= mid)
		I (left, l, mid, L, R), swp[right] = 0, tr[right] = 0, all[right] = 0;
	else if (L > mid)
		I (right, mid + 1, r, L, R), swp[left] = 0, tr[left] = 0, all[left] = 0;
	else
		I (left, l, mid, L, mid), I (right, mid + 1, r, mid + 1, R);

	tr[x] = tr[left] + tr[right];

	return ;

}

void D (const int x, const int l, const int r, const int L, const int R) {

	if (l == L && r == R) {

		tr[x] = r - l + 1 - tr[x];

		all[x] = 1, swp[x] = 0;

		return ;

	}

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	if (R <= mid)
		D (left, l, mid, L, R);
	else if (L > mid)
		D (right, mid + 1, r, L, R);
	else
		D (left, l, mid, L, mid), D (right, mid + 1, r, mid + 1, R);

	tr[x] = tr[left] + tr[right];

	return ;

}

void C (const int x, const int l, const int r, const int L, const int R) {

	if (l == L && r == R) {

		tr[x] = r - l + 1 - tr[x], swp[x] = 1;

		return ;

	}

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	if (R <= mid)
		C (left, l, mid, L, R), swp[right] = 0, tr[right] = 0, all[right] = 0;
	else if (L > mid)
		C (right, mid + 1, r, L, R), swp[left] = 0, tr[left] = 0, all[left] = 0;
	else
		C (left, l, mid, L, mid), C (right, mid + 1, r, mid + 1, R);

	tr[x] = tr[left] + tr[right];

	return ;

}

void S (const int x, const int l, const int r, const int L, const int R) {

	if (l == L && r == R) {

		tr[x] = r - l + 1 - tr[x];
		
		swp[x] = 1;

		return ;

	}

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	if (R <= mid)
		S (left, l, mid, L, R);
	else if (L > mid)
		S (right, mid + 1, r, L, R);
	else
		S (left, l, mid, L, mid), S (right, mid + 1, r, mid + 1, R);

	tr[x] = tr[left] + tr[right];

	return ;

}

void Q (const int x, const int l, const int r) {

	if (l == r) {
//		if (l <= 10) cerr << l << ':' << tr[x] << '\n';
		ans[l] = tr[x];

		return ;

	}

	const int mid = l + r >> 1, left = x << 1, right = left | 1;

	pushdown (x, left, right, l, r, mid);

	Q (left, l, mid), Q (right, mid + 1, r);

	return ;

}
//void debug () {Q (1, 0, n); for (int i = 0; i <= 10; ++ i) cerr << ans[i]; cerr << '\n'; return ;}
int main () {

	ios::sync_with_stdio (0);

	cin.tie (0);

	cout.tie (0);

	build (1, 0, n);

	while (cin >> op >> opl >> l >> opr >> r >> opr) {

		l <<= 1, r <<= 1;

		if (opl == '(')
			++ l;

		if (opr == ')')
			-- r;

		if (l > r)
			continue ;

		if (op == 'U')
			U (1, 0, n, l, r);
		else if (op == 'I')
			I (1, 0, n, l, r);
		else if (op == 'D')
			D (1, 0, n, l, r);
		else if (op == 'C')
			C (1, 0, n, l, r);
		else
			S (1, 0, n, l, r);
//		debug ();
	}

	Q (1, 0, n);

	for (int i = 0; i <= n; ++ i)
		if (ans[i]) {

			if (! i || ! ans[i - 1])
				l = i;

			if (! ans[i + 1])
				cout << (l & 1 ? '(' : '[') << (l >> 1) << ',' << (i + 1 >> 1) << (i & 1 ? ')' : ']'), flag = 1;

		}

	if (! flag)
		cout << "empty set";

	return 0;

}
/*
U [1,5]
D [3,3]

0 1 2 3 4 5
00111111111
00111101111
00110010011
00001101100
00000100000
*/

我先下线,明天看回复qaq

2024/8/17 00:32
加载中...