[CF482B]Interesting Array

题目大意:构造一个序列$S$,有$m$条限制,每条为$l;r;q$,表示$&_{i=l}^r S_i=q$

题解:每条限制就把$[l,r]$内的数或上$q$,最后判断就行了

卡点:我又写了一课$O(n^2log_2n)$的线段树。。。

C++ Code:

#include <cstdio>
#include <cstdlib>
#define maxn 100010
const int inf = (1 << 30) - 1;
namespace SgT {
	int n;
	int L, R, q;
	int V[maxn << 2], tg[maxn << 2];
	inline void pushdown(int rt) {
		int &x = tg[rt];
		V[rt << 1] |= x;
		V[rt << 1 | 1] |= x;
		tg[rt << 1] |= x;
		tg[rt << 1 | 1] |= x;
		x = 0;
	}
	void modify(int rt, int l, int r) {
		if (L <= l && R >= r) {
			V[rt] |= q;
			tg[rt] |= q;
			return ;
		}
		if (tg[rt]) pushdown(rt);
		int mid = l + r >> 1;
		if (L <= mid) modify(rt << 1, l, mid);
		if (R > mid) modify(rt << 1 | 1, mid + 1, r);
		V[rt] = V[rt << 1] & V[rt << 1 | 1];
	}
	inline void add(int ll, int rr, int qq) {
		L = ll, R = rr, q = qq;
		modify(1, 1, n);
	}
	int query(int rt, int l, int r) {
		if (L <= l && R >= r) return V[rt];
		if (tg[rt]) pushdown(rt);
		int mid = l + r >> 1, ans = inf;
		if (L <= mid) ans = query(rt << 1, l, mid);
		if (R > mid) ans &= query(rt << 1 | 1, mid + 1, r);
		return ans;
	}
	inline int ask(int ll, int rr) {
		L = ll, R = rr;
		return query(1, 1, n);
	}
}
using SgT::add;
using SgT::ask;
int n, m;
int l[maxn], r[maxn], q[maxn];
int main() {
	scanf("%d%d", &n, &m); SgT::n = n;
	for (int i = 1; i <= m; i++) {
		scanf("%d%d%d", l + i, r + i, q + i);
		add(l[i], r[i], q[i]);
	}
	for (int i = 1; i <= m; i++) {
		if (ask(l[i], r[i]) != q[i]) {
			puts("NO");
			exit(0);
		}
	}
	puts("YES");
	for (int i = 1; i < n; i++) printf("%d ", ask(i, i));
	printf("%d
", ask(n, n));
	return 0;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/9753778.html