Interesting Array

题目大意

构造一个序列 \(a\),使其满足若干限制条件,每个限制条件是形如 l r q 的式子,其意义是:\(\&_{i=l}^ra_i=q\)。

题意分析

看上去是构造题,实际上是数据结构题。

我们不妨先令初始时 \(a\) 为一个全 \(0\) 序列,再逐一看每个限制条件。

为了满足某一个限制条件 \(l,r,p\),\([l,r]\) 区间的数必须符合以下两点:

  • \(1\),在二进制表示中,\(p\) 为 \(1\) 的位置均为 \(1\)。
  • \(2\),在二进制表示中,\(p\) 为 \(0\) 的位置区间内至少有一个数该位为 \(0\)。

我们发现,同时构造出满足两个条件的序列比较麻烦,且不好判断无解,因此,我们可以让一个条件成为构造的依据,另一个条件成为判断的依据。

具体的说,我们只需要构造出满足其中一个条件的序列,再逐一判断每个区间是否满足另一个条件即可。

因此,我们不妨先构造一个满足条件 \(1\) 的序列,再逐一对条件 \(2\) 进行判断。

那么,现在问题就变成了如果构造一个满足条件 \(1\) 的序列和如何对条件 \(2\) 进行判断。

这其实很简单,我们只需要用线段树进行区间按位或和区间求按位与就行了。

这是因为为了满足条件 \(1\),我们需要让区间的二进制表示包含 \(p\),这等价于于区间按位或 \(p\),而条件 \(2\) 与区间的按位与是 \(p\) 二者也等价。

综上,我们只需要维护一颗线段树,支持区间或和区间求与即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=100100; int n,m,inp[N][3]; struct STn{int l,r,t,sum;};//sum表示区间与的结果,t是懒标记
struct ST{
STn a[N<<2];
void or_t(int p,int k){
a[p].t|=k;a[p].sum|=k;//都或上k
}
void push_down(int p){//下放懒标记
if(a[p].t){
or_t(p<<1,a[p].t);
or_t(p<<1|1,a[p].t);
a[p].t=0;
}
}
void build(int p,int l,int r){//简单建树
a[p].l=l;a[p].r=r;a[p].t=0;
if(a[p].l==a[p].r) return ;
int mid=(a[p].l+a[p].r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void or_all(int p,int l,int r,int k){//区间或
if(l<=a[p].l&&a[p].r<=r){or_t(p,k);return ;}
push_down(p);int mid=(a[p].l+a[p].r)>>1;
if(l<=mid) or_all(p<<1,l,r,k);
if(r>mid) or_all(p<<1|1,l,r,k);
a[p].sum=a[p<<1].sum&a[p<<1|1].sum;
}
int and_all(int p,int l,int r){//区间求与
if(l<=a[p].l&&a[p].r<=r) return a[p].sum;
push_down(p);int mid=(a[p].l+a[p].r)>>1;
if(r<=mid) return and_all(p<<1,l,r);
if(l>mid) return and_all(p<<1|1,l,r);
return and_all(p<<1,l,r)&and_all(p<<1|1,l,r);
}
void print(int p){//输出序列
if(a[p].l==a[p].r){cout<<a[p].sum<<' ';return ;}
push_down(p);int mid=(a[p].l+a[p].r)>>1;
print(p<<1);print(p<<1|1);
}
}tree; int main(){
scanf("%d%d",&n,&m);
tree.build(1,1,n);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&inp[i][0],&inp[i][1],&inp[i][2]);
tree.or_all(1,inp[i][0],inp[i][1],inp[i][2]);
}
for(int i=1;i<=m;i++)
if(tree.and_all(1,inp[i][0],inp[i][1])!=inp[i][2]){cout<<"NO\n";return 0;}
cout<<"YES\n";
tree.print(1);
return 0;
}

Interesting Array 题解的更多相关文章

  1. B. Interesting Array(线段树)

    B. Interesting Array time limit per test 1 second memory limit per test 256 megabytes input standard ...

  2. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

  3. codeforces 482B. Interesting Array【线段树区间更新】

    题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...

  4. Codeforces 482B Interesting Array(线段树区间更新)

    题目链接 Interesting Array 区间更新.然后对于每一个约数重新求一遍区间的&值,不符合就跳出. #include <bits/stdc++.h> using nam ...

  5. Codeforces E. Interesting Array(线段树)

    题目描述: D. Interesting Arraytime limit per test1 secondmemory limit per test256 megabytesinputstandard ...

  6. [LeetCode]Remove Duplicates from Sorted Array题解

    Remove Duplicates from Sorted Array: Given a sorted array, remove the duplicates in place such that ...

  7. Leetcode Find Minimum in Rotated Sorted Array 题解

    Leetcode Find Minimum in Rotated Sorted Array 题目大意: 对一个有序数组翻转, 就是随机取前K个数,移动到数组的后面,然后让你找出最小的那个数.注意,K有 ...

  8. [CF482B]Interesting Array

    题目大意:构造一个序列$S$,有$m$条限制,每条为$l\;r\;q$,表示$\&_{i=l}^r S_i=q$ 题解:每条限制就把$[l,r]$内的数或上$q$,最后判断就行了 卡点:我又写 ...

  9. Codeforces Round #275 Div.1 B Interesting Array --线段树

    题意: 构造一个序列,满足m个形如:[l,r,c] 的条件. [l,r,c]表示[l,r]中的元素按位与(&)的和为c. 解法: 线段树维护,sum[rt]表示要满足到现在为止的条件时该子树的 ...

  10. Codeforces 482B Interesting Array

    题意:构造一个长度为n的序列,使其满足m个形式如下如下约束:a[l]&a[l+1]&a[l+2]&....&a[r]=q 从Dalao的博客上看到这题,决定去水水.做法 ...

随机推荐

  1. 学习C++这一篇就够了(提升篇)

    C++中除了面向对象的编程思想外,还有另一种就是泛型编程 主要用到的技术就是模板 模板机制的分类: 函数模板 类模板 函数模板 作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体定制,用虚拟 ...

  2. Maven项目配置

    pom.xml配置 配置编码格式为UTF-8 <properties> <project.build.sourceEncoding>UTF-8</project.buil ...

  3. 使用 virt-install 命令创建虚拟机

    实践 参考文档:官方手册 这个命令适用于创建第一个虚拟机,后面如果再增加,修改xml文件或者使用clone命令就可以了. centos.sh #!/bin/bash name='centos7' is ...

  4. 2021-3-9 保存csv格式文件

    public void SaveCSV(DataTable dt, string fullPath) { FileInfo fi = new FileInfo(fullPath); if (!fi.D ...

  5. Python工具箱系列(三十九)

    使用zlib对数据进行压缩 现实世界中,大量存在着对数据压缩的需求.为此,python内置了zlib压缩库,可以方便的对任意对象进行压缩. 下述代码演示了对字符串进行压缩: import zlib # ...

  6. Java 生态需要新鲜的血液、需要狂飙的刺激。Solon v2.4.1 发布

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...

  7. grub加密与解密

    前言 grub默认无加密,用户可免密以单用户模式进入系统修改root密码.若想增强其安全性,可以将grub加密. GRUB2提供两种类型的密码保护: 修改菜单条目时需要密码,但启动菜单条目时不需要密码 ...

  8. C#性能优化-树形结构递归优化

    前言 大家好,我是wacky,最近在工作中遇到一个有趣的问题,同事反馈说WPF中有一个树形结构的集合,在加载时会直接报堆栈溢出,一直没时间(懒得)看,导致很久了也没人解决掉.于是,组长就把这个&quo ...

  9. python中将时间转换为时间戳

    某平台url中的时间格式为时间戳,将时间变量传入url前,需要将固定格式的时间转换为时间戳.使用python中的time模块,对时间的几种格式进行转换. strptime(),将时间字符串转换成 结构 ...

  10. Flutter系列文章-Flutter UI进阶

    在本篇文章中,我们将深入学习 Flutter UI 的进阶技巧,涵盖了布局原理.动画实现.自定义绘图和效果.以及 Material 和 Cupertino 组件库的使用.通过实例演示,你将更加了解如何 ...