主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多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. vs2008发布项目失败的解决方法

    解决办法: 要知道发布是怎么失败的,用组合键"Ctrl+Alt+O"即可,仔细查看信息可发现有没发布成功的详细提示,然后在资源管理器中找到那一项,删除或排除到项目外,重新生成之后再 ...

  2. ScheduledThreadPoolExecutor 使用线程池执行定时任务

    转自:https://segmentfault.com/a/1190000008038848 在现实世界里,我们总是免不了要定期去做一件事情(比如上课)—— 在计算机的世界里,更是如此.比如我们手机每 ...

  3. day11-元组与字典

    1.元组Tuple与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用中括号.元组可以查询,可以使用内置函数count.index.但是不能修改.增加.删除(儿子不能,孙子有可能). ...

  4. 现学现卖——VS2013 C#测试

    VS2013 C#测试 首先安装Unit Test Generator.方法为:工具->扩展和更新->联机->搜索“Unit Test Generator”,图标为装有蓝色液体的小试 ...

  5. 固定顶部指定div不滑动

    .fixed_div { position:fixed; z-index:100; top: 45px; width:100%; height:45px; } 指定div设置属性position:fi ...

  6. Linux命令:history

    显示历史(执行过的)命令. history [n] history -c history -d offset history -anrw [filename] history -p arg [arg ...

  7. WebStorm新创建项目介绍

    WebStorm创建一个项目 这里支持有很多的类型项目: Empty Project         ----一个空的项目 Html5 Boilerplate     ----HTML5开发框架 We ...

  8. [ SHELL编程 ] 文件内容大小写替换

    shell编程经常会碰到字符串.文件内容大小写的转换,在不同的场景下选择合适的命令可以提高编程效率. 适用场景 需大小写转换的文件内容或字符串 字符串大小写替换 小写替换大写 echo "h ...

  9. map和hasmap的区别

    MAP接口的定义如下: public interface MAP< k , v>      Key 到value 的映射 ,Key不允许重复,每一个key只能映射一个value . Has ...

  10. ckeditor使用说明

      2015-08-17 15:42热心网友最快回答 一.使用方法:1.在页面<head>中引入ckeditor核心文件ckeditor.js<script type="t ...