主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位有0和1两种情况,0表示这个区间不存在这种颜色,1就表示存在,我在这里用到或运算,我们确定一个非叶子节点的值时,可以把它的两个儿子节点的值做或运算,只要某一位有1,那么这一位就是1了,这样就完成了颜色的上传。看代码吧。

建树:

struct node{
int w,f;    //w是颜色的二进制表示的值,f是懒标记
}tree[*+];
int n,m,k,t,a,b,c,ans;
void build(int l,int r,int k)
{
tree[k].f=;
if(l==r)
{
tree[k].w=(<<);  //初始都是2,把二进制第二位变成1
return;
}
int mid=(l+r)/;
build(l,mid,k*);
build(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}

区间修改:(区间是a到b,颜色是c)

void change_interval(int l,int r,int k)
{
if(l>=a&&r<=b)
{
tree[k].f=c;  
tree[k].w=(<<(c-));
return ;
}
if(tree[k].f) //下传懒标记
down(k);
int mid=(l+r)/;
if(mid>=a)
change_interval(l,mid,k*);
if(mid<b)
change_interval(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}

区间查询:我把所有颜色都保存到了ans里

void ask_interval(int l,int r,int k)
{
if(l>=a&&r<=b)
{
ans|=tree[k].w;
return;
}
if(tree[k].f)
down(k);
int mid=(l+r)/;
if(a<=mid)
ask_interval(l,mid,k*);
if(b>mid)
ask_interval(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}

完整代码:

#include<iostream>
#include<cstring>
using namespace std;
struct node{
int w,f;
}tree[*+];
int n,m,k,t,a,b,c,ans;
void build(int l,int r,int k)
{
tree[k].f=;
if(l==r)
{
tree[k].w=(<<);
return;
}
int mid=(l+r)/;
build(l,mid,k*);
build(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}
void down(int k)
{
tree[k*].f=tree[k].f;
tree[k*+].f=tree[k].f;
tree[k*].w=<<(tree[k].f-);
tree[k*+].w=<<(tree[k].f-);
tree[k].f=;
}
void change_interval(int l,int r,int k)
{
if(l>=a&&r<=b)
{
tree[k].f=c;
tree[k].w=(<<(c-));
return ;
}
if(tree[k].f)
down(k);
int mid=(l+r)/;
if(mid>=a)
change_interval(l,mid,k*);
if(mid<b)
change_interval(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}
void ask_interval(int l,int r,int k)
{
if(l>=a&&r<=b)
{
ans|=tree[k].w;
return;
}
if(tree[k].f)
down(k);
int mid=(l+r)/;
if(a<=mid)
ask_interval(l,mid,k*);
if(b>mid)
ask_interval(mid+,r,k*+);
tree[k].w=tree[k*].w|tree[k*+].w;
}
int main()
{
while(cin>>n>>m)
{
if(!n&&!m)
break;
build(,n,);
for(int i=;i<m;i++)
{
char ch[];
cin>>ch;
if(ch[]=='P')
{
cin>>a>>b>>c;
change_interval(,n,);
}
else if(ch[]=='Q')
{
cin>>a>>b;
ans=;
ask_interval(,n,);
int ss[],cnt=; //这个ss数组是为了保存颜色,好控制格式
memset(ss,,sizeof(ss));
for(int i=;i<=;i++)
{
if(&(ans>>(i-)))
ss[++cnt]=i;
}
for(int i=;i<=cnt;i++)
{
if(i!=cnt)
cout<<ss[i]<<' ';
else
cout<<ss[i]<<endl;
}
}
}
}
return ;
}

hdu 5023 线段树+位运算的更多相关文章

  1. hdu 5023 线段树+状压

    http://acm.hdu.edu.cn/showproblem.php?pid=5023 在片段上着色,有两种操作,如下: 第一种:P a b c 把 a 片段至 b 片段的颜色都变为 c . 第 ...

  2. poj 3225 线段树+位运算

    略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset 采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内U T S ← S ∪ T 即将[l, ...

  3. POJ 2777 Count Color(线段树+位运算)

    题目链接:http://poj.org/problem?id=2777 Description Chosen Problem Solving and Program design as an opti ...

  4. poj 2777 Count Color - 线段树 - 位运算优化

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42472   Accepted: 12850 Description Cho ...

  5. Codeforces 620E New Year Tree(线段树+位运算)

    题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...

  6. Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

    链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...

  7. Count Color(线段树+位运算 POJ2777)

    Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 39917 Accepted: 12037 Descrip ...

  8. HDU 5023线段树区间染色,统计区间内颜色个数

    这个也是一个线段树的模板 #include<iostream> #include<string.h> #include<algorithm> #include< ...

  9. hdu 5023 线段树延迟更新+状态压缩

    /* 线段树延迟更新+状态压缩 */ #include<stdio.h> #define N 1100000 struct node { int x,y,yanchi,sum; }a[N* ...

随机推荐

  1. LInux 阿里云系统遇到挖矿程序

    参考 https://blog.csdn.net/qq_37837029/article/details/82314428 重要的一点,移除下面文件里面的定时任务 /var/spool/cron/cr ...

  2. 尚硅谷springboot学习15-日志框架1-入门

    引子 小张:开发一个大型系统 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? ​ 2.框架来记录系统的一些运行时信息:日志框架 : ...

  3. C++中文件读写的操作

    在C++中读读写文件一般指的就是磁盘中的文本文件和二进制文件: 文本文件:以字符序列组成的文件 二进制文件:由二进制组成的文件 读写文件采用ofstream和ifstream文件流,两者可用头文件&l ...

  4. [SQL]UNPIVOT 多個欄位

    有朋友問「如何直接unpivot成2個欄位」,如下所示, 先準備測試資料如下, view source print? 01 create table T ( 02 no varchar(10), 03 ...

  5. 4.HTTP入门.md

    目录 什么是http协议 http协议:对浏览器客户端 和 服务器端 之间数据传输的格式规范 查看http协议的工具* 使用火狐的firebug插件(右键->firebug->网络) Ht ...

  6. unity3d assetbundle打包策略

    由于assetbundle打包存在依赖的问题,所有资源要进行合理的分包 零.代码 代码都放在本地,包括NGUI等插件的代码.shader代码(内置的shader无需打包,而自定义的shader还是需要 ...

  7. unity 三种注入示例

    /* * 演示Unity 注入 * */ using Microsoft.Practices.Unity; using System; namespace Unity.Property.Inject ...

  8. Oracle 查询版本号

    select * from v$version; -- 或 select banner from sys.v_$version;

  9. selenium 浏览器常用设置和部署

    一,chrome浏览器设置 from selenium import webdriver # 浏览器选项 chrome_options = webdriver.ChromeOptions() # 使用 ...

  10. 解决SMARTFORMS文本编辑器不能打开

    在DEV打开SMARTFORMS文本编辑器时,出现如下错误 由于宏安全设置,无法找到宏或宏被禁用. 解决方法如下: 在DEV环境新建程序后输入如下代码执行即可. *&------------- ...