CodeForces 482B 有趣的数列
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
给你一个非负整数组成的数列a
[1], a[2], ..., a[n] ,如果它满足m个约束,我们就称它为有趣数列。每个约束包含3个整数
li,
ri,
qi (
1 ≤ li ≤ ri ≤ n)
表示
等于
qi.
请找出这样的一个序列。
Input
第一行两个整数n, m (1 ≤ n ≤ 105, 1 ≤ m ≤ 105) —数列长度和约束个数.
接下来m行 li, ri, qi (1 ≤ li ≤ ri ≤ n, 0 ≤ qi < 230) 表示第i个约束.
Output
如果存在这样一个数列,输出 "YES" (没有括号) 第二行输出a[1], a[2], ..., a[n] (0 ≤ a[i] < 230) . 如果有多解,请输出任意一组。
如果无解输出 "NO"(没有括号).
Sample Input
3 1
1 3 3
3 2
1 3 3
1 3 2
Sample Output
YES
3 3 3
NO
解题思路:
题目描述的很清楚了
1,首先这题给了一堆的约束,然后让你给任意一组正确的答案,那么就是按照约束构造数组咯
2,然后每个约束是指一个区间内的数&起来的等于一个指定的值q
3,然后分析分析一下就可以发现,每一个约束都让这个区间内的数可以等于q
4,那就是让个区间内的数都或q(初始这个数组是0的,或运算可以让二进制的1保留下来)
5,所有的约束都执行完之后,最后再检测一遍,是不是形成的数组可以满足每一个约束
6,可以的话就输出这个数组,ok了
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 100005;
int n,m;
int col[maxn<<2];
int sum[maxn<<2];
int we ;
int getss(){
we = 0 ;
for(int i=1;i<=31;i++){
we<<=1;
we|=1 ;
}
}
void PushUp(int rt) {
sum[rt] = sum[rt<<1] & sum[rt<<1|1];
}
void PushDown(int rt) {
if (col[rt]) {
//printf("rt = %d\n",col[rt]);
col[rt<<1] |=col[rt];
col[rt<<1|1] |= col[rt];
sum[rt<<1] |= col[rt];
sum[rt<<1|1] |= col[rt];
col[rt] = 0;
}
}
void update(int L,int R,int c,int l,int r,int rt) {
if (L <= l && r <= R) {
col[rt] = col[rt]|c;
sum[rt] = sum[rt]|c;
return ;
}
PushDown(rt);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (R > m) update(L , R , c , rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt) {
if (L <= l && r <= R) {
//if(l==r)printf("rt = %d\n",sum[rt]);
return sum[rt];
}
PushDown(rt);
int m = (l + r) >> 1;
int ret = we;
//printf("%d\n",we);
if (L <= m) ret =ret&query(L , R , lson);
//printf("ret1 = %d\n",ret);
if (m < R) ret = ret&query(L , R , rson);
//printf("ret2 = %d\n",ret);
//PushUp(rt);
return ret;
}
int a[maxn];
int b[maxn];
int c[maxn] ;
int main() {
getss() ;
//freopen("in.txt","r",stdin);
//printf("%d\n",1<<30);
while(~scanf("%d%d",&n,&m)){
memset(col,0,sizeof(col)) ;
memset(sum,0,sizeof(sum)) ;
for(int i=0;i<m;i++){
//int a,b,c ;
scanf("%d%d%d",&a[i],&b[i],&c[i]) ;
update(a[i],b[i],c[i],1,n,1) ;
}
//for(int i=1;i<=n;i++)query(i,i,1,n,1);
bool flag = true ;
for(int i=0;i<m;i++){
//printf("q = %d\n",query(a[i],b[i],1,n,1));
if(c[i]!=query(a[i],b[i],1,n,1)){
flag = false ;
break ;
}
}
if(flag){
printf("YES\n");
for(int i=1;i<n;i++){
printf("%d ",query(i,i,1,n,1)) ;
}printf("%d\n",query(n,n,1,n,1));
}else{
printf("NO\n");
}
}
return 0;
}