[2018.10.15 T1] 或
阿新 • • 發佈:2018-11-09
暫無連線
或
【題目描述】
小Q非常喜歡序列和位運算。
有一天,小Q想到了一個模型:一個長度為 的非負整數序列 ,滿足 個條件:第 個條件為 。他想知道是否存在一個序列滿足條件,如果存在,他還要構造出一個這樣的序列。
【輸入】
第一行兩個整數 。接下來 行每行三個整數 。
【輸出】
如果存在這樣的序列 ,第一行輸出Yes,第二行輸出 個不超過 的非負整數表示 ,否則輸出一行 。
【輸入樣例】
2 1
1 2 1
【輸出樣例】
Yes
1 1
【提示】
【資料規模及約定】
對於
的資料,
。
對於另外
的資料,
。
對於
的資料,
。
題解
如果一段區間 起來某幾位等於 ,那麼該區間的這幾位必須全部為 ,所以我們開 個序列維護每一位,通過查分做區間賦 操作。
最後按照我們構造出的每一位得出答案,用線段樹 一下即可。
程式碼
#include<bits/stdc++.h>
#define ls v<<1
#define rs v<<1|1
using namespace std;
const int M=1e5+5,bit=30;
int que[bit+2][M],ans[M],sum[M<<2],l[M],r[M],p[M],n,m;
void in(){scanf("%d%d",&n,&m);}
void up(int v){sum[v]=sum[ls]|sum[rs];}
void build(int v,int l,int r)
{
if(l==r){sum[v]=ans[l];return;}
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
up(v);
}
int ask(int v,int le,int ri,int lb,int rb)
{
if(lb<=le&&ri<=rb){return sum[v];}
int mid=le+ri>>1,ans=0;
if(lb<=mid)ans=ask(ls,le,mid,lb,rb);
if(mid<rb)ans|=ask(rs,mid+1,ri,lb,rb);
return ans;
}
void ac()
{
for(int i=0;i<bit;++i)que[i][0]=1;
for(int i=1,j;i<=m;++i)
{
scanf("%d%d%d",&l[i],&r[i],&p[i]);
for(j=0;j<bit;++j)
if(!(p[i]>>j&1))--que[j][l[i]],++que[j][r[i]+1];
}
for(int i=0,j;i<bit;++i)for(j=1;j<=n;++j)que[i][j]+=que[i][j-1];
for(int i=0,j;i<bit;++i)for(j=1;j<=n;++j)if(que[i][j]==1)ans[j]|=1<<i;
build(1,1,n);
for(int i=1;i<=m;++i)if(ask(1,1,n,l[i],r[i])!=p[i])puts("No"),exit(0);
puts("Yes");for(int i=1;i<=n;++i)printf("%d ",ans[i]);
}
int main(){in(),ac();}