#線段樹#A 或位運算
阿新 • • 發佈:2020-10-13
題目
一個長度為\(n\)的非負整數序列,
需要滿足\(m\)個區間或值為閾值的限制條件
現在要構造一個這樣的序列,不存在輸出No
分析
線段樹支援區間與,但查詢區間或,下傳標記,那就很好做了
程式碼
#include <cstdio> #include <cctype> #define rr register using namespace std; const int inf = (1 << 30) - 1, N = 100011; int a[N], w[N << 2], lazy[N << 2], n, m, l[N], r[N], z[N]; inline signed iut() { rr int ans = 0; rr char c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) ans = (ans << 3) + (ans << 1) + (c ^ 48), c = getchar(); return ans; } inline void print(int ans) { if (ans > 9) print(ans / 10); putchar(ans % 10 + 48); } inline void build(int k, int l, int r) { w[k] = lazy[k] = inf; if (l == r) return; rr int mid = (l + r) >> 1; build(k << 1, l, mid); build(k << 1 | 1, mid + 1, r); } inline void pdown(int k) { w[k << 1] &= lazy[k], w[k << 1 | 1] &= lazy[k], lazy[k << 1] &= lazy[k], lazy[k << 1 | 1] &= lazy[k], lazy[k] = inf; } inline void update(int k, int l, int r, int x, int y, int z) { if (l == x && r == y) { w[k] &= z, lazy[k] &= z; return; } rr int mid = (l + r) >> 1; if (lazy[k] ^ inf) pdown(k); if (y <= mid) update(k << 1, l, mid, x, y, z); else if (x > mid) update(k << 1 | 1, mid + 1, r, x, y, z); else update(k << 1, l, mid, x, mid, z), update(k << 1 | 1, mid + 1, r, mid + 1, y, z); w[k] = w[k << 1] | w[k << 1 | 1]; } inline signed query(int k, int l, int r, int x, int y) { if (l == x && r == y) return w[k]; rr int mid = (l + r) >> 1; if (lazy[k] ^ inf) pdown(k); if (y <= mid) return query(k << 1, l, mid, x, y); else if (x > mid) return query(k << 1 | 1, mid + 1, r, x, y); else return query(k << 1, l, mid, x, mid) | query(k << 1 | 1, mid + 1, r, mid + 1, y); } inline void dfs(int k, int l, int r) { if (l == r) { a[l] = w[k]; return; }; rr int mid = (l + r) >> 1; if (lazy[k] ^ inf) pdown(k); dfs(k << 1, l, mid); dfs(k << 1 | 1, mid + 1, r); w[k] = w[k << 1] | w[k << 1 | 1]; } signed main() { freopen("or.in", "r", stdin); freopen("or.out", "w", stdout); n = iut(), m = iut(), build(1, 1, n); for (rr int i = 1; i <= m; ++i) { l[i] = iut(), r[i] = iut(), z[i] = iut(); update(1, 1, n, l[i], r[i], z[i]); } for (rr int i = 1; i <= m; ++i) if (query(1, 1, n, l[i], r[i]) < z[i]) return !printf("No"); dfs(1, 1, n), printf("Yes"); for (rr int i = 1; i <= n; ++i) putchar(i == 1 ? 10 : 32), print(a[i]); return 0; }