您的位置:首页 > 其它

codeforces 482B Interesting Array 线段树

2014-10-27 12:06 344 查看
传送门:cf 482B

长度为n的数组,现在要求li到ri的值相与值为qi,问是否存在这样的数组

每一段相与为q时,对应位置对应位上的值必须为1,于是把对应位的值赋1,初步得到一个数组

然后利用线段判断对应段的值与q是否相等,

/******************************************************
* File Name:   b.cpp
* Author:      kojimai
* Create Time: 2014年10月26日 星期日 15时59分48秒
******************************************************/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define FFF 100005
int flag[FFF],l[FFF],r[FFF],q[FFF],a[FFF];
struct node {
int l,r,v;
}p[FFF*4];

void build(int l,int r,int num) {
p[num].l = l;p[num].r = r;
p[num].v = -1;
if(l == r) {
p[num].v = a[l];
return;
}
int mid = (l+r) >> 1;
build(l,mid,num*2);
build(mid+1,r,num*2+1);
}
int query(int l,int r,int num)
{
int mid = (p[num].l+p[num].r) >> 1;
if(p[num].l == l &&p[num].r == r)
{
if(p[num].v != -1)
return p[num].v;
else {
p[num].v = query(l,mid,num*2)&query(mid+1,r,num*2+1);
return p[num].v;
}
}
if(r<=mid)
return query(l,r,num*2);
else if(l>mid)
return query(l,r,num*2+1);
else {
int ans = query(l,mid,num*2);
ans = ans & query(mid+1,r,num*2+1);
return ans;
}
}

int main()
{
int n,m;
cin>>n>>m;
memset(a,0,sizeof(a));
for(int i = 0;i < m;i++)
cin>>l[i]>>r[i]>>q[i];
for(int bit = 0; bit < 30;bit++) {
memset(flag,0,sizeof(flag));
for(int i = 0; i < m;i++) {
if((1<<bit)&q[i]) {
flag[l[i]-1]++;
flag[r[i]]--;
}
}
int now = 0;
for(int i = 1;i <= n;i++) {
now += flag[i-1];
if(now > 0)
a[i] |= (1<<bit);
}
}
build(1,n,1);
bool flag = true;
for(int i = 0;i < m && flag;i++) {
if(query(l[i],r[i],0) != q[i])
flag = false;
}
if(flag) {
printf("YES\n");
for(int i = 1;i <= n;i++)
{
if(i<n)
printf("%d ",a[i]);
else
printf("%d\n",a[i]);
}
}
else
printf("NO\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: