http://blog.csdn.net/niuox/article/details/9664487

这道题明显是线段树,根据题意可以知道:

(用0和1表示是否包含区间,-1表示该区间内既有包含又有不包含)

U:把区间[l,r]覆盖成1

I:把[-∞,l)(r,∞]覆盖成0

D:把区间[l,r]覆盖成0

C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换

S:[l,r]区间0/1互换

这里有两个地方和区间更新不一样

一个是会更新选中区间以外的所有区域,可以这样子解决:

void update(char val,int L,int R,int l,int r,int rt)
{
...
int mid = (l + r)>>;
if (L <= mid)
{
update(val,L,R,l,mid,rt<<);
}
else if(val == 'I' || val == 'C')
{
a[rt<<] = col[rt<<] = ;
}
if(R > mid)
{
update(val,L,R,mid+,r,rt<<|);
}
else if(val == 'I' || val == 'C')
{
a[rt<<|] = col[rt<<|] = ;
}
}

if判断左边是否小于mid,如果不是,那么更新它的左边就是我们想要的选中区域外了,右边同理。

第二个是有两种更新方式,覆盖和异或

这种问题一般需要两种标记,但这里其中一种是覆盖,所以一种标记可以用值自身表示,-1表示杂,非-1表示纯。一个标记数组就行。

然后还要理清两种标记使用的方式

很明显我们可以知道这个性质:

当一个区间被覆盖后,不管之前有没有异或标记都没有意义了
所以当一个节点得到覆盖标记时把异或标记清空

第三种是开闭区间,这里可以通过把所有数乘2处理(偶数表示端点,奇数表示两端点间的区间)。

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 65535*2
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f int n,m; int a[MAXN<<],col[MAXN<<],ans; bool vis[MAXN]; void FXOR(int x)
{
if(a[x]!=-) a[x]^=;
else col[x]^=;
} void PushDown(int rt)
{
if(a[rt] != -)
{
a[rt<<] = a[rt<<|] = a[rt];
col[rt<<] = col[rt<<|] = ;
a[rt] = -;
}
if(col[rt])
{
FXOR(rt<<);
FXOR(rt<<|);
col[rt] = ;
}
} void update(char val,int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R)
{
if(val == 'U')
{
a[rt] = ;
col[rt] = ;
}
else if(val == 'D')
{
a[rt] = col[rt] = ;
}
else if(val == 'C' || val == 'S')
{
FXOR(rt);
}
return;
}
PushDown(rt);
int mid = (l + r)>>;
if (L <= mid)
{
update(val,L,R,l,mid,rt<<);
}
else if(val == 'I' || val == 'C')
{
a[rt<<] = col[rt<<] = ;
}
if(R > mid)
{
update(val,L,R,mid+,r,rt<<|);
}
else if(val == 'I' || val == 'C')
{
a[rt<<|] = col[rt<<|] = ;
}
} void query(int l,int r,int rt)
{
if(a[rt] == )
{
for(int i = l;i<=r;i++) vis[i] = true;
return;
}
else if(a[rt] == ) return;
if(l == r) return;
PushDown(rt);
int mid = (l + r)>>;
query(l,mid,rt<<);
query(mid+,r,rt<<|);
} int main()
{
int r,t;
char op,lchar,rchar;
a[] = col[] = ;
while(~sf("%c %c%d,%d%c\n",&op,&lchar,&r,&t,&rchar))
{
r<<=;
t<<=;
if(lchar == '(') r++;
if(rchar == ')') t--;
update(op,r,t,,MAXN,);
}
query(,MAXN,);
int s = -,e;
bool flag = false;
for(int i=;i<=MAXN;i++)
{
if(vis[i])
{
if(s == -) s = i;
e = i;
}
else
{
if(s!=-)
{
if(flag) pf(" ");
pf("%c%d,%d%c",s&?'(':'[',s>>,(e+)>>,e&?')':']');
s = -;
flag = true;
}
}
}
if(!flag) printf("empty set");
return ; }

POJ 3225 线段树区间更新(两种更新方式)的更多相关文章

  1. POJ 3225 (线段树 区间更新) Help with Intervals

    这道题搞了好久,其实坑点挺多.. 网上找了许多题解,发现思路其实都差不多,所以就不在重复了. 推荐一篇比较好的题解,请戳这. 另外,如果因为可能要更新多次,但最终查询只需要一次,所以没有写pushup ...

  2. HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)

    HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...

  3. POJ 3667 线段树区间合并

    http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html 用线段树,首先要定义好线段树的节点信息,一般看到一个问题,很难很 ...

  4. poj 2528 线段树区间修改+离散化

    Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...

  5. Mayor's posters POJ - 2528 线段树区间覆盖

    //线段树区间覆盖 #include<cstdio> #include<cstring> #include<iostream> #include<algori ...

  6. poj 3468 线段树区间更新/查询

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  7. hdu 1698+poj 3468 (线段树 区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...

  8. poj 2777 线段树 区间更新+位运算

    题意:有一个长板子,分成多段,有两种操作,第一种是C给从a到b那段染一种颜色c,另一种是P询问a到b有多少种不同的颜色.Sample Input2 2 4  板长 颜色数目 询问数目C 1 1 2P ...

  9. POJ 3667 线段树区间合并裸题

    题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回. 建立线段树,值为1表示未租出,0为租出 ...

随机推荐

  1. .Generator与其他异步处理方案

    1.Generator与其他异步处理方案 以前,异步编程的方法,大概有下面四种. 1.1 回调函数 JavaScript 语言对异步编程的实现,就是回调函数.所谓回调函数,就是把任务的第二段单独写在一 ...

  2. Python3之Memcache使用

    简介 Memcached是一个高性能的分布式内存对象缓存系统,用于动态WEB应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态,数据库网站的速度.Memcached ...

  3. 自已的sql server练习小记

    print getdate(); print datediff(year,'1987-09-13',getdate()) select * from CallRecords select top 5 ...

  4. 用qt creator创建可继承ui类

    https://jingyan.baidu.com/article/5d368d1efa2dd73f60c05786.html 用qt creator创建可继承ui类 听语音 | 浏览:1657 | ...

  5. css类选择器中 空格 逗号 啥都不填的区别及其他笔记

    .a.b 代表 一个元素上 同时 有 a 类 和 b 类 .a .b (中间有空格) 代表 .b 是 .a 的子元素选择. .a,.b 代表 class='a' 和 class='b' 都会被选择上.

  6. python之控制流习题+代码

    # !/usr/bin/python3 # -*- coding: utf-8 -*- # @Time :2018/11/26 15:32 # @Author :yosef # @Email :wur ...

  7. 【算法笔记】B1030 完美数列(三种方法)

    1030 完美数列 (25 分) 给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可 ...

  8. luogu4931. 情侣?给我烧了!(加强版)(错位排列)

    题目链接 https://www.luogu.org/problemnew/show/P4931 题解 以下部分是我最开始的想法. 对于每一个 \(k\),满足恰好有 \(k\) 对情侣和睦的方案数为 ...

  9. [转] CSS 选择器参考手册

    [From] http://www.w3school.com.cn/cssref/css_selectors.asp CSS3 选择器 在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. ...

  10. Oracle Merge 使用

    <转自> http://blog.csdn.net/nsj820/article/details/5755685 Oracle9i引入了MERGE命令,你能够在一个SQL语句中对一个表同时 ...