CodeForces 482B 有趣的数列 数据结构+线段树+位运算的技巧

来源:互联网 发布:网络接口转换器怎么用 编辑:程序博客网 时间:2024/04/29 00:16

CodeForces 482B 有趣的数列

Time Limit:1000MS    Memory Limit:262144KB    64bit IO Format:%I64d & %I64u

SubmitStatusPracticeCodeForces 482B

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 | 1const 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;}


0 0