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

这道题搞了好久,其实坑点挺多。。

网上找了许多题解,发现思路其实都差不多,所以就不在重复了。

推荐一篇比较好的题解,请戳这

另外,如果因为可能要更新多次,但最终查询只需要一次,所以没有写pushup函数,仅有一个pushdown。

  1 #include <cstdio>
  2
  3 const int maxn = 131072;
  4 //const int maxn = 10;
  5 int qL, qR, op;
  6 int setv[maxn << 2], xorv[maxn << 2];
  7 bool in[maxn + 10];
  8
  9 void pushdown(int o)
 10 {
 11     int lc = o*2, rc = o*2+1;
 12     if(setv[o] >= 0)
 13     {
 14         setv[lc] = setv[rc] = setv[o];
 15         setv[o] = -1;
 16         xorv[lc] = xorv[rc] = 0;
 17     }
 18     if(xorv[o])
 19     {
 20         if(setv[lc] >= 0) setv[lc] ^= 1; else xorv[lc] ^= 1;
 21         if(setv[rc] >= 0) setv[rc] ^= 1; else xorv[rc] ^= 1;
 22         xorv[o] = 0;
 23     }
 24 }
 25
 26 void update(int o, int L, int R, int qL, int qR)
 27 {
 28     if(qL <= L && qR >= R)
 29     {
 30         if(op == 1) { setv[o] = xorv[o] = 0; }
 31         else if(op == 2) { setv[o] = 1; xorv[o] = 0; }
 32         else if(op == 3) { if(setv[o] >= 0) setv[o] ^= 1; else xorv[o] ^= 1; }
 33         return;
 34     }
 35     int M = (L + R) / 2;
 36     pushdown(o);
 37     if(qL <= M) update(o*2, L, M, qL, qR);
 38     if(qR > M) update(o*2+1, M+1, R, qL, qR);
 39 }
 40
 41 void query(int o, int L, int R)
 42 {
 43     if(setv[o] >= 0)
 44     {
 45         if(setv[o] == 1) for(int i = L; i <= R; i++) in[i] = true;
 46         return;
 47     }
 48     pushdown(o);
 49     if(L == R) return;
 50     int M = (L + R) / 2;
 51     query(o*2, L, M);
 52     query(o*2+1, M+1, R);
 53 }
 54
 55 char cmd, _left, _right;
 56
 57 int main()
 58 {
 59     //freopen("in.txt", "r", stdin);
 60
 61     while(scanf("%c %c%d,%d%c\n", &cmd, &_left, &qL, &qR, &_right) >= 0)
 62     {
 63         qL <<= 1; qR <<= 1;
 64         if(_left == ‘(‘) qL++; if(_right == ‘)‘) qR--;
 65         if(qL > qR && (cmd == ‘I‘ || cmd == ‘C‘)) { setv[1] = 0; xorv[1] = 0; continue; }
 66         if(cmd == ‘U‘) { op = 2; update(1, 0, maxn, qL, qR); }
 67         else if(cmd == ‘I‘)
 68         {
 69             op = 1;
 70             if(qL - 1 >= 0) update(1, 0, maxn, 0, qL-1);
 71             if(qR + 1 <= maxn) update(1, 0, maxn, qR+1, maxn);
 72         }
 73         else if(cmd == ‘D‘) { op = 1; update(1, 0, maxn, qL, qR); }
 74         else if(cmd == ‘C‘)
 75         {
 76             op = 1;
 77             if(qL - 1 >= 0) update(1, 0, maxn, 0, qL-1);
 78             if(qR + 1 <= maxn) update(1, 0, maxn, qR+1, maxn);
 79             op = 3;
 80             update(1, 0, maxn, qL, qR);
 81         }
 82         else if(cmd == ‘S‘) { op = 3; update(1, 0, maxn, qL, qR); }
 83     }
 84     query(1, 0, maxn);
 85     bool print = false;
 86     int s = -1, e;
 87     for(int i = 0; i <= maxn; i++)
 88     {
 89         if(in[i])
 90         {
 91             if(s == -1) s = i;
 92             e = i;
 93         }
 94         else if(s != -1)
 95         {
 96             if(print) printf(" ");
 97             print = true;
 98             printf("%c%d,%d%c", s&1?‘(‘:‘[‘, s>>1, (e+1)>>1, e&1?‘)‘:‘]‘);
 99             s = -1;
100         }
101     }
102
103     if(!print) puts("empty set");
104
105     return 0;
106 }

代码君

时间: 2024-09-28 12:55:21

POJ 3225 (线段树 区间更新) Help with Intervals的相关文章

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

http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注意 是改为z,不是加或减,最后输出区间总值 也是线段树加lazy操作 1 #include<cstdio> 2 using namespace std; 3 struct point { 4 int l,r; 5 int val,sum; 6 }; 7 point tree[400007]; 8

POJ 2777 &amp;&amp; ZOJ 1610 &amp;&amp;HDU 1698 --线段树--区间更新

直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 -- 区间更新的话 分为 增减 或者 修改 主要就是个 laze 标记 就是延迟更新 对于区间更新的写法 一般是有2种 其一 仔细划分到每个细小的区间    另一 粗略划分 反正 ==我的代码里会给出2种写法 看自己喜好 hdu 1 //线段树 成段更新 ---> 替换 根结点的查询 2 3 #i

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

POJ 2777 Count Color (线段树区间更新加查询)

Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a positive integer, so we can evenly d

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

线段树 + 区间更新 + 模板 ---- poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59798   Accepted: 18237 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

线段树区间更新+向量知识——POJ 2991

对应POJ题目:点击打开链接 Crane Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description ACM has bought a new crane (crane -- je?áb) . The crane consists of n segments of various lengths, connected by flexible joints

poj 3468 A Simple Problem with Integers (线段树区间更新入门)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 70442   Accepted: 21723 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 2777 Count Color (线段树区间更新)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37647   Accepted: 11315 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.