线段树求调
查看原帖
线段树求调
938933
Dtw_楼主2024/3/9 10:43

具体思路就是维护每个区间的左边的值,右边的值,以及这个区间是否合法,合并的时候先判断左右儿子是否合法,再判断左儿子的 右端点 是否 不等于 右儿子的 左端点 的值,如果成立那这个大区间就合法

样例过了,测试数据过了 15 个,wa 了 27 个

求调 qwq

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'

#define TRACE 1
#define tcout TRACE && cout

#define fi first
#define se second

#define IN(o) insert(o)

#define int long long

#define fst ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

const int INF = 0x3f3f3f3f3f3f3f3f;

const int P = 998244353;

const int N = 2e6 + 10;

int n, q;

char a[N];
int c[N];

struct Node
{
	int l, r;
	int la, ra;
	int lzy;
	bool f;
};

#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define mid ((l+r) >> 1)

Node tr[N<<2];

inline void push_up(int rt)
{
	if(tr[lson].f && tr[rson].f && tr[lson].ra != tr[rson].la)
	{
		tr[rt].f = 1;
	}
	else
	{
		tr[rt].f = 0;
	}
	tr[rt].la = tr[lson].la;
	tr[rt].ra = tr[rson].ra;
}

void build(int rt, int l, int r)
{
	tr[rt] = {l, r, 0, 0, 0, 0};
	if(l == r)
	{
		tr[rt].la = c[l];
		tr[rt].ra = c[l];
		tr[rt].f = 1;
		return ;
	}
	build(lson, l, mid);
	build(rson, mid+1, r);
	push_up(rt);
}

void push_down(int rt)
{
	if(tr[rt].lzy == 0)
	{
		return ;
	}
	tr[lson].lzy ^= 1;
	tr[rson].lzy ^= 1;
	tr[lson].la ^= 1;
	tr[lson].ra ^= 1;
	tr[rson].la ^= 1;
	tr[rson].ra ^= 1;
	tr[rt].lzy = 0;
}

void upd(int rt, int sp, int ep)
{
	int l = tr[rt].l;
	int r = tr[rt].r;
	if(sp <= l && r <= ep)
	{
		tr[rt].la ^= 1;
		tr[rt].ra ^= 1;
		tr[rt].lzy ^= 1;
		return ;
	}
	push_down(rt);
	if(sp <= mid)
	{
		upd(lson, sp, ep);
	}
	if(ep > mid)
	{
		upd(rson, sp, ep);
	}
	push_up(rt);
}

Node query(int rt, int sp, int ep)
{
	int l = tr[rt].l;
	int r = tr[rt].r;
	if(sp <= l && r <= ep)
	{
		return tr[rt];
	}
	push_down(rt);
	if(ep <= mid)
	{
		return query(lson, sp, ep);
	}
	if(sp > mid)
	{
		return query(rson, sp, ep);
	}
	auto L = query(lson, sp, ep);
	auto R = query(rson, sp, ep);
	Node res;
	if(L.ra != R.la && L.f && R.f)
	{
		res.f = 1;
	}
	else
	{
		res.f = 0;
	}
	return res;
}


signed main()
{
	fst;
	cin >> n >> q;
	for(int i=1; i<=n; i++)
	{
		cin >> a[i];
		c[i] = a[i] - '0';
	}
	build(1, 1, n);
	while(q--)
	{
		int op, l, r;
		cin >> op >> l >> r;
		if(op == 1)
		{
			upd(1, l, r);
		}
		else
		{
			auto res = query(1, l, r);
			if(res.f)
			{
				cout << "Yes" << endl;
			}
			else
			{
				cout << "No" << endl;
			}
		}
	}
	return 0;
}




2024/3/9 10:43
加载中...