主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多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. Flex学习笔记--多层菜单按钮

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  2. python中的递归小实例

    #1.n! def fact(n): if n == 0: return 1 else: return n*fact(n-1)print(fact(10)) #2.斐波那契数列F(n)=F(n-1)+ ...

  3. 列表(list) 的 基本操作

    举例说明:names = ["zhangyang", "guyun", 'xiangpeng', ['alex','jack'], "xuliangc ...

  4. How to start a VirtualBox VM headless in Windows 10

    If you wanted to start a VirtualBox VM headless (no UI) in the past, you needed additional tools.  I ...

  5. UI5-学习篇-16-云端SCP-Destination配置

    1.登录路径: https://account.ap1.hana.ondemand.com/#/home/welcome 2.查看云连接器 如下图所示,虚拟主机都已连接且资源可用: 若虚拟主机连接存在 ...

  6. 跟我一起学Python-day1(条件语句以及初识变量)

    通过练习题来学习条件语句 1,使用while循环输出1 2 3 4 5 6    8  9  10 n=1 while n<11: if n=7: pass else: print(n) n=n ...

  7. css:自己实现一个带小图标的input输入框

    有小图标的input输入框<input type="text" placeholder="输入手机号" style="background:ur ...

  8. shell命令中用source 和sh(或者bash)执行脚本的区别,以及export的作用

    用户登录到Linux系统后,系统将启动一个用户shell,我们暂且称这个shell为shell父. 在这个shell父中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程序. 当使用 ...

  9. 【382】利用 namedtuple 实现函数添加属性

    namedtuple 能够实现类似类的效果,tuple 的元素可以通过属性的形式返回,如下所示: from collections import namedtuple Student = namedt ...

  10. TCP/IP网络协议的通俗理解,SOCKET,HTTP,SOAP

    TCP/IP,HTTP,SOAP等协议之区别   术语TCP/IP代表传输控制协议/网际协议,指的是一系列协议.“IP”代表网际协议,TCP和UDP使用该协议从一个网络传送数据包到另一个网络.把IP想 ...