[CF482B]Interesting Array

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

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

卡点:我又写了一课$O(n^2\log_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\n", ask(n, n));
	return 0;
}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/9753778.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值