• POJ 3225 成段更新 并补集.cpp


    题意:

      给出一些集合和原来的集合进行多种运算,输出运算后的结果..

      

    输入:

      T a b 表示是原集合与该集合进行T操作~

      一开始集合为空..

      最后输出结果~如果是空集合就输出empty set

     

    思路:

      这道题巧妙的地方是根据集合操作的特点把运算改成了成段的数据更新..

      

      线段树延迟标记延迟了更新的结果..

     

      根据集合操作的特点..

      可以看出:

        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互换

      其中如果该区间接受到了覆盖标记..那原来的异或标记就可以清零了..

      至于开闭区间可以通过 把每个点看成两个点..其中奇数表示该点是开区间..偶数表示该点是闭区间..

     

      两个数组..XOR--异或标记..COVER--覆盖标记..

     

      FXOR:

        
        当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记

      pushDown:

        当一个节点得到覆盖标记时把异或标记清空

        向下更新的时候根据覆盖标记和异或标记进行更新.. 

        记得更新完节点后该点要归为原始状态..

      modify:

        先找到范围..然后根据运算特点对区间内的数进行更新..

        更新完之后就可以返回了~

        如果没在范围内~就先向下更新节点~然后进行判断更新..

      query:

        找到对应的范围然后进行标记..

     

    Tips:

        各种更新各种细节吖~要好好理解然后再做~

        

    Code:

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <iostream>
      4 using namespace std;
      5 
      6 const int MAXN = 131072;
      7 int cover[MAXN<<2], XOR[MAXN<<2];
      8 bool vis[MAXN+1];
      9 
     10 void FXOR(int rt)
     11 {
     12     if(cover[rt] != -1) cover[rt] ^= 1;
     13     else XOR[rt] ^= 1;
     14 }
     15 
     16 void pushDown(int rt) {
     17     if(cover[rt] != -1) {
     18         cover[rt<<1] = cover[rt<<1|1] = cover[rt];
     19         cover[rt] = -1;
     20         XOR[rt<<1] = XOR[rt<<1|1] = 0;///!!!
     21     }
     22     if(XOR[rt]) {
     23         FXOR(rt<<1);
     24         FXOR(rt<<1|1);
     25         XOR[rt] = 0;
     26     }
     27 }
     28 
     29 void modify(char opt, int l, int r, int L, int R, int rt) {
     30     if(l <= L && r >= R) {
     31         if(opt == 'U') {
     32             cover[rt] = 1;
     33             XOR[rt] = 0;
     34         }
     35         else if(opt == 'D'){
     36             cover[rt] = 0;
     37             XOR[rt] = 0;///!!!
     38         }
     39         else if(opt == 'C' || opt == 'S')
     40             FXOR(rt);
     41         return;
     42     }
     43     //if(l == r) return;
     44     pushDown(rt);
     45     int mid = (L+R)>>1;
     46     if(l <= mid) modify(opt, l, r, L, mid, rt<<1);
     47     else if(opt == 'I' || opt == 'C')
     48         cover[rt<<1] = XOR[rt<<1] = 0;///!!!
     49     if(r > mid) modify(opt, l, r, mid+1, R, rt<<1|1);
     50     else if(opt == 'I' || opt == 'C')
     51         cover[rt<<1|1] = XOR[rt<<1|1] = 0;///!!!
     52 }
     53 
     54 void query(int l, int r, int rt) {
     55         if(cover[rt] == 1) {
     56             for(int i = l; i <= r; ++i)
     57                 vis[i] = 1;
     58             return;//!!!
     59         }
     60         else if(cover[rt] == 0) return;
     61     if(l == r) return;
     62     pushDown(rt);
     63     int mid = (l+r)>>1;
     64     query(l, mid, rt<<1);
     65     query(mid+1, r, rt<<1|1);
     66 }
     67 
     68 int main()
     69 {
     70     int i, j, k;
     71     char opt, c, cc;
     72     int a, b;
     73     int st = -1, en;
     74     bool flag = false;
     75     while(scanf("%c %c %d,%d %c", &opt, &c, &a, &b, &cc) != EOF) {
     76         getchar();
     77         a *= 2, b *= 2;
     78         if(c == '(') a++;
     79         if(cc == ')') b--;
     80         if(a > b) {
     81             if(opt == 'I' || opt == 'C')
     82             cover[1] = XOR[1] = 0;
     83         } else modify(opt, a, b, 0, MAXN, 1);
     84     }
     85     query(0, MAXN, 1);
     86     for(i = 0; i <= MAXN; ++i) {///!!!
     87         if(vis[i]) {
     88             if(st == -1) st = i;
     89             en = i;
     90         } else if(vis[i] == 0 && st != -1) {
     91             if(flag) printf(" ");
     92             printf("%c%d,%d%c", st%2?'(':'[', (st)/2, (en+1)/2, en%2?')':']');
     93             flag = true;
     94             st = -1;//!!!
     95         }
     96     }
     97     if(!flag) printf("empty set");
     98     puts("");
     99     return 0;
    100 }

    题目链接:http://poj.org/problem?id=3225

  • 相关阅读:
    bzoj 2038 [2009国家集训队]小Z的袜子(hose)
    【NOIP2014模拟11.1B组】吴传之火烧连营
    【NOIP2014模拟11.1B组】蜀传之单刀赴会
    phpmystudy:mysql启动失败
    英文漏洞报告解读(一)——PHP 5.4.x < 5.4.32 Multiple Vulnerabilities
    brupsuit Compare 模块及其应用场景
    Android实现Banner界面广告图片循环轮播(包括实现手动滑动循环)
    android ViewPager实现的轮播图广告自定义视图,网络获取图片和数据
    Android首页轮播图直接拿来用
    java 调用webservice的各种方法总结
  • 原文地址:https://www.cnblogs.com/Griselda/p/2743935.html
Copyright © 2020-2023  润新知