这题纠结了两天,开始一点思路没有,后来看到有大牛把这题的做法称作区间树,并说明了区间树与线段树的区别(区间树是区间内被染色的区间标记为1,未被染色的区间标记为0)。我觉得这就是线段树的一类操作,没有必要分出去吧。。。

思路:区间更新,首先想到的应该是Lazy思想;这题分五种情况:

Command Semantics
U T S ← S ∪ T
I T S ← S ∩ T
D T S ← S − T
C T S ← T − S
S T S ← S ⊕ T

U:直接将T对应的区间覆盖为1;

I:将T的补区间(比如T[l, r], 补区间就是[0, l-1], [r+1, N])清零即可;

D:直接将T区间清零;

C:先将T的补区间清零,再对T区间取反;

S:直接对T区间取反;

(把这几个操作在纸上写写,马上就明白了。)

然后就是剩下的线段树的区间更新、区间上传、区间下分了。

Code:

#include <iostream>#include <cstdio>#include <cstring>#define L(t)    t << 1#define R(t)     t << 1 | 1using namespace std;

const int N = 65540*2;

class node{public:int l, r;int cov;int change;    //表示该区间是否需要被改变;void changeEdit(){        //按change进行操作if(change)    change = 0;    //如果需要改变,当前区间标为不需要else if(cov != -1)    cov ^= 1;        //如果当前段非单色, 对他进行^改变else     change = 1;        }}node[N*4];

int flag[N];

// 下分void PushDown(int t){if(node[t].cov != -1){        node[L(t)].cov = node[R(t)].cov = node[t].cov;        node[L(t)].change = node[R(t)].change = node[t].change;    }if(node[t].change){        node[L(t)].changeEdit();        node[R(t)].changeEdit();        node[t].change = 0;    }}//上传void PushUp(int t){if(node[L(t)].cov == node[R(t)].cov){        node[t].cov = node[L(t)].cov;    } else {        node[t].cov = -1;    }}

void creat(int t, int l, int r){    node[t].l = l;    node[t].r = r;    node[t].cov = 0;    node[t].change = 0;

if(l == r)    return ;

int mid = (l + r) >> 1;

    creat(L(t), l, mid);    creat(R(t), mid+1, r);}

void updata(int t, int l, int r, int v){if(node[t].l > l || node[t].r < r)    return ;

if(node[t].l >= l && node[t].r <= r){//printf("%d %d %d\n", l, r, v);        node[t].cov = v;        node[t].change = 0;return ;    }

    PushDown(t);int mid = (node[t].l + node[t].r) >> 1;

if(l > mid)        updata(R(t), l, r, v);else if(r <= mid)        updata(L(t), l, r, v);else{        updata(L(t), l, mid, v);        updata(R(t), mid+1, r, v);    }    PushUp(t);}

void XOR(int t, int l, int r){if(node[t].l > l || node[t].r < r)    return ;

if(node[t].l == l && node[t].r == r){//printf("%d %d %d\n", l, r, node[t].cov);if(node[t].cov != -1)            node[t].cov ^= 1;else            node[t].change ^= 1;return ;    }

    PushDown(t);int mid = (node[t].l + node[t].r) >> 1;

if(l > mid)        XOR(R(t), l, r);else if(r <= mid)        XOR(L(t), l, r);else{        XOR(L(t), l, mid);        XOR(R(t), mid + 1, r);    }    PushUp(t);}

void query(int t){if(node[t].l == node[t].r){        flag[node[t].l] = node[t].cov;return ;    }    PushDown(t);    query(L(t));    query(R(t));}

int main(){//freopen("data.in", "r", stdin);

int l, r, i;char s, p, q;

    creat(1, 0, N);

while(~scanf("%c %c%d,%d%c\n", &s, &p, &l, &r, &q)){        l *= 2;    r *= 2;if(p == '(')    l++;if(q == ')')    r--;

if(s == 'U'){            updata(1, l, r, 1);        } else if(s == 'I'){if(l > 0)                updata(1, 0, l - 1, 0);if(r < N)                updata(1, r + 1, N, 0);        } else if(s == 'D'){            updata(1, l, r, 0);        } else if(s == 'C'){if(l > 0)                updata(1, 0, l - 1, 0);if(r < N)                updata(1, r + 1, N, 0);            XOR(1, l, r);        } else{            XOR(1, l, r);        }    }    query(1);int begin, end, tmp = 1;for(i = 0; i <= N; i++){while(i <= N && !flag[i])    i++;        begin = i;if(i > N)    break;

while(i <= N && flag[i])    i++;        end = i - 1;

        tmp = 0;

if(begin&1){            printf("(%d,", begin/2);        } else{            printf("[%d,", begin/2);        }

if(end&1){            printf("%d) ", (end+1)/2);        }else{            printf("%d] ", end/2);        }    }if(tmp)        printf("empty set");    putchar('\n');return 0;}

POJ 3225 Help with Intervals(线段树)相关推荐

  1. POJ 1177 Picture [离散化+扫描线+线段树]

    http://poj.org/problem?id=1177 给若干矩形,求被覆盖的区域的周长. 将 y 坐标离散化后,按 x 坐标进行扫描.用线段树维护两个东西,当前竖线的叠加长度 len 和 条数 ...

  2. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

  3. poj 2777 AND hdu 5316 线段树

    区间染色问题,用线段树可以解决.颜色总类不多,故考虑用二进制数的每一位表示一种颜色,然后父节点的颜色就是孩子节点颜色"或"起来,加上lazy标记,轻松AC. poj 2777: 1 ...

  4. POJ 2777 Count Color (线段树区间修改 + 状态压缩)

    题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时  板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...

  5. POJ——3624 Balanced Lineup(线段树入门——区间最值问题)

    原题链接:http://poj.org/problem?id=3264 每天挤奶时,农夫John的N头奶牛(1≤N≤50,000头)总是按照相同的顺序排列.一天,农夫约翰决定和几头牛组织一场极限飞盘游 ...

  6. poj 2985(并查集+线段树求K大数)

    解题思路:这道题并查集很容易,合并时找到父节点就直接加上去就ok了.关键是如何求K大数,我一直在想用线段树怎么写,一开始想如果直接记录数的大小那肯定是没戏了,借鉴了一下别人的思路:区间[a,b]记录的 ...

  7. poj 2528 Mayor's posters (线段树+离散化)

    /*离散化+线段树由于 数据的输入最大是 10000000 ,直接用开数组肯点会超,所以要将起离散话,首先 ,我们存储输入的边,将其离散化,后面的就和一般的线段树一样可. */#include< ...

  8. Poj 3246 Balanced Lineup(线段树基础)

    依旧是线段树基础题 询问区间的最大值和最小值之差,只有询问,没有插入删除.继续理解基础线段树 #include <iostream> #include <algorithm> ...

  9. POJ 3264 Balanced Lineup 【线段树】

    Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 50004 Accepted: 23434 Cas ...

最新文章

  1. python3菜鸟教程中文-Python3 字符串
  2. Winform中实现中文验证码(附代码下载)
  3. Maven软件的下载安装
  4. UNIX网络编程——解决TCP网络传输“粘包”问题
  5. Spring MVC:MySQL和Hibernate的安全性
  6. MyEclipse 皮肤、主题、背景色
  7. python输出引号内的变量值_引号中的Python变量值
  8. 按键精灵手机版去除广告XPosed模块插件
  9. 根据 List 元素中的某个字段大小排序
  10. 英特尔第十代处理器为什么不支持win7_为什么i7处理器不支持win7系统,背后的真实原因?...
  11. QComboBox下拉框给选项增加删除按钮
  12. 计算机组成原理中英文名词对照_持续更新
  13. 吴恩达深度学习笔记(五)
  14. (2/2) sharex录制屏幕没有声音,升级高版本的 sharex
  15. Wangle源码分析:Service
  16. 分享如何恢复回收站删除文件的办法
  17. 前端请求接口报405错误
  18. 不容错过的Java高级面试题
  19. 下载RoboWare Studio官网登录不上去
  20. 小学计算机课认识键盘,教学设计:《认识键盘》

热门文章

  1. jenkins如何实现重新发布历史构建记录里的版本
  2. angularjs 日期倒计时效果
  3. 数据结构 排序(希尔排序)
  4. linux :故障提示:Error:No suitable device found: no device found for connection System eth0
  5. Power BI for Office 365(七) Power BI站点
  6. jquery 鼠标经过显示 信息小卡片
  7. 富有客户端技术之——jQuery EasyUI
  8. 申请加入 “WebGIS” 团队
  9. QWidget子窗口中setStyleSheet无效,解决方法
  10. Ubuntu 14.04更新为国内阿里源解决apt-get install无法执行的问题