初始化全,操作视为区间与,之后区间查或看是否满足条件
以上操作都可以使用线段树
#include <iostream>
using namespace std;
int n;
int m;
struct Lrv {
int l;
int r;
int v;
};
struct Node {
// int sum = (1 << 30) - 1;
// int tag = (1 << 30) - 1;
int sum;
int tag;
Node(): sum((1 << 30) - 1), tag((1 << 30) - 1) {}
void AddTag(int x) {
sum &= x;
tag &= x;
}
};
Node xds[808080];
Lrv lrvs[202020];
void PushDown(int p) {
if (xds[p].tag != (1 << 30) - 1) {
xds[p << 1].AddTag(xds[p].tag);
xds[p << 1 | 1].AddTag(xds[p].tag);
xds[p].tag = (1 << 30) - 1;
}
}
void Update(int p) {
xds[p].sum = xds[p << 1].sum | xds[p << 1 | 1].sum;
}
void Andi(int l, int r, int v, int p, int lp, int rp) {
if (r < lp || rp < l) {
return;
}
if (l <= lp && rp <= r) {
// cout << v << ',' << lp << ',' << rp << endl;
xds[p].AddTag(v);
return;
}
PushDown(p);
int mid = (lp + rp) >> 1;
Andi(l, r, v, p << 1, lp, mid);
Andi(l, r, v, p << 1 | 1, mid + 1, rp);
Update(p);
}
int Or(int l, int r, int p, int lp, int rp) {
if (r < lp || rp < l) {
return 0;
}
if (l <= lp && rp <= r) {
return xds[p].sum;
}
PushDown(p);
int mid = (lp + rp) >> 1;
return Or(l, r, p << 1, lp, mid) | Or(l, r, p << 1 | 1, mid + 1, rp);
}
void Output(int p, int l, int r) {
if (l == r) {
cout << xds[p].sum << ' ';
return;
}
PushDown(p);
int mid = (l + r) >> 1;
Output(p << 1, l, mid);
Output(p << 1 | 1, mid + 1, r);
}
void Solve() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
auto& [l, r, v] = lrvs[i];
cin >> l >> r >> v;
Andi(l, r, v, 1, 1, n);
}
for (int i = 0; i < m; i++) {
const auto& [l, r, v] = lrvs[i];
if (Or(l, r, 1, 1, n) != v) {
cout << "-1";
return;
}
}
Output(1, 1, n);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Solve();
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号