Codeforces Round #816 D
D. 2+ doors
俗话说的好 正难则反 首先思考其合法性 就让我们够头痛的了
我们反向思考 让他们最开始就是满足合法性的 那么我们可以怎么做呢
把每一个都初始化成最大值 要是有 i j x 与之相关就让 a[i]&=x a[j]&=x 这样做出来的 a 合法性显然的同时 还是最大的
让后我们要最小的 考虑在合法性正确的情况下减小 我们知道 a|b=x a的最小值是b^x
也就是我们本来a|b=x 但是有的位置上是俩1 我们可以让a消掉一个1 但是还是要满足其他位置上的合法性 所以要把最终结果|起来
注意还要有个特判就是 i==j 时就直接是x了 不让会被异或成0
#include <bits/stdc++.h>
using namespace std;
const int N =1e6+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define Endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
void solve() {
int n,q;cin>>n>>q;
vector<int>a(n+1,(1<<30)-1);
vector<vector<pair<int,int>>>g(n+1);
while(q--){
int i,j,x;cin>>i>>j>>x;
a[i]&=x;a[j]&=x;
g[i].emplace_back(j,x);
g[j].emplace_back(i,x);
}
for(int i=1;i<=n;i++){
int res=0;
for(auto &[j,x]:g[i]){
if(i==j){
res=x;
break;
}
res|=x^a[j];
}
a[i]=res;
}
for(int i=1;i<=n;i++)cout<<a[i]<<' ';
}
signed main(){
fast
int T;T=1;
while(T--) {
solve();
}
return ~~(0^_^0);
}