主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多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. 恺撒密码 I Python实现

    '''恺撒密码 I描述凯撒密码是古罗马凯撒大帝用来对军事情报进行加解密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列中该字符后面的第三个字符,即,字母表的对应关系如下:原文:A ...

  3. elasticsearch-ik

    因lucene默认采用英文且英文通过空格就可以断句.而中文则是词组,如果不加载中文词库或插件则会变为一个一个字而非词组,因此需要加载中文词库. 不加分词库所看到的中文分词效果. post _analy ...

  4. cp命令 复制目录

    格式:cp -R {源目录地址} {目标目录地址} 假设文件夹download下有两个目录 download/a download/b 现在想将文件夹a复制到文件夹b下,执行 cp -R downlo ...

  5. Delphi TMemoryStream写入到字符串和字符串写入到流

    一.TMemoryStream数据写入到字符串里 var lvStream:TMemoryStream; s:AnsiString; p: PAnsiChar; begin lvStream:= TM ...

  6. leetcode AC1 感受

    在网上第一个AC还是蛮高兴的,之前试了不少练习编程的方法,感觉不怎么适合自己,在OJ上做题的确是一个能够锻炼的方法. 之前一直研究学习的方法,往简单的说是认知.练习,往复杂的说是,保持足够input, ...

  7. ADO数据库操作方式

    微软公司的ADO (ActiveX Data Objects) 是一个用于存取数据源的COM组件.它提供了编程语言和统一数据访问方式OLE DB的一个中间层.允许开发人员编写访问数据的代码而不用关心数 ...

  8. String特殊值的判断方式

    对String的特殊值的判断上,除了要关注是否为null,还要关注是否是空字符串. 经常处理的时候直接判断是否为Null就好了,这样很容易出现问题: if(null!=str) { //not goo ...

  9. ReactiveX 学习笔记(11)对 LINQ 的扩展

    Interactive Extensions(Ix) 本文的主题为对 Ix 库,对 LINQ 的扩展. Buffer Ix.NET Buffer Ix.NET BufferTest Buffer 方法 ...

  10. Haskell语言开发工具

    Stack How to Script with Stack Originate Guides - Haskell Tool Stack 配置 Intellij Idea IntelliJ plugi ...