zoukankan      html  css  js  c++  java
  • poj3225(线段树区间更新&hash)

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

    题意: 初始给一个全局为 0~65536 的区间  s, 然后不断地对区间 s 进行 并, 交, 差, 相对差等运算, 输出最终结果;

    思路: 很显然是线段树区间操作的路子, 但要 AC 还需细细斟酌;

    下面一段题解摘自博客: http://blog.csdn.net/metalseed/article/details/8039326

    我们一个一个操作来分析:(用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互换

    成段覆盖的操作很简单,比较特殊的就是区间0/1互换这个操作,我们可以称之为异或操作
    很明显我们可以知道这个性质:当一个区间被覆盖后,不管之前有没有异或标记都没有意义了
    所以当一个节点得到覆盖标记时把异或标记清空
    而当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记

    开区间闭区间只要数字乘以2就可以处理(偶数表示端点,奇数表示两端点间的区间)
    线段树功能:update:成段替换,区间异或 query:简单hash

     

    代码:

     

     1 #include <stdio.h>
     2 #include <iostream>
     3 #define lson l, mid, rt << 1
     4 #define rson mid + 1, r, rt << 1 | 1
     5 using namespace std;
     6 
     7 const int MAXN = 65536 << 1;
     8 bool hash[MAXN + 1];//hash标记答案
     9 int cover[MAXN << 2], Xor[MAXN << 2];//cover为区间的0/1状态, Xor为区间的转换状态
    10 
    11 void Fxor(int rt){//更新区间转换状态
    12     if(cover[rt] != -1) cover[rt] ^= 1;//当前区间标记为0 或 1
    13     else Xor[rt] ^= 1;//当前区间既有0, 又有 -1 的情况
    14 }
    15 
    16 void push_down(int rt){//将标记推到下一层
    17     if(cover[rt] != -1){
    18         cover[rt << 1] = cover[rt << 1 | 1] = cover[rt];
    19         Xor[rt << 1] = Xor[rt << 1 | 1] = 0;//清空标记
    20         cover[rt] = -1;
    21     }
    22     if(Xor[rt]){
    23         Fxor(rt << 1);
    24         Fxor(rt << 1 | 1);
    25         Xor[rt] = 0;
    26     }
    27 }
    28 
    29 void update(char op, int L, int R, int l, int r, int rt){//区间更新
    30     if(L <= l && R >= r){
    31         if(op == 'U'){
    32             cover[rt] = 1;
    33             Xor[rt] = 0;
    34         }else if(op == 'D'){
    35             cover[rt] = 0;
    36             Xor[rt] = 0;
    37         }else if(op == 'C' || op == 'S') Fxor(rt);
    38         return;
    39     }
    40     push_down(rt);//向下更新
    41     int mid = (l + r) >> 1;
    42     if(L <= mid) update(op, L, R, lson);
    43     else if(op == 'I' || op == 'C'){
    44         Xor[rt << 1] = cover[rt << 1] = 0;//当op为I或C时,若当前[l, r]不在[L, R]内,则清空
    45     }
    46     if(R > mid) update(op, L, R, rson);
    47     else if(op == 'I' || op == 'C'){
    48         Xor[rt << 1 | 1] = cover[rt << 1 | 1] = 0;
    49     }
    50 }
    51 
    52 void query(int l, int r, int rt){
    53     if(cover[rt] == 1){
    54         for(int i = l; i <= r; i++){
    55             hash[i] = true;
    56         }
    57         return;
    58     }else if(cover[rt] == 0) return;
    59     if(l == r) return;
    60     push_down(rt);
    61     int mid = (l + r) >> 1;
    62     query(lson);
    63     query(rson);
    64 }
    65 
    66 
    67 int main(void){
    68     int l, r;
    69     char op, a, b;
    70     while(~scanf("%c %c%d,%d%c", &op, &a, &l, &r, &b)){
    71         getchar();
    72         l <<= 1;
    73         r <<= 1;
    74         if(a == '(') l++;
    75         if(b == ')') r--;
    76         if(l > r){//输入区间为 (1, 1)这样的情况
    77             if(op == 'I' || op == 'C') cover[1] = Xor[1] = 0;
    78         }else update(op, l, r, 0, MAXN, 1);
    79     }
    80     query(0, MAXN, 1);
    81     bool flag = false;
    82     int s = -1, e;//记录当前区间开头和结尾位置
    83     for(int i = 0; i <= MAXN; i ++){
    84         if(hash[i]){
    85             if(s == -1) s = i;
    86             e = i;
    87         }else{
    88             if(s != -1){
    89                 if(flag) printf(" ");
    90                 flag = true;
    91                 printf("%c%d,%d%c", s&1 ? '(' : '[', s>>1, (e + 1)>>1, e&1 ? ')' : ']');
    92                 s = -1;
    93             }
    94         }
    95     }
    96     if(!flag) printf("empty set");
    97     puts("");
    98     return 0;
    99 }
    View Code

     

     

  • 相关阅读:
    【模板】Sparse-Table
    UVa 11235 Frequent values
    【模板】树状数组
    UVa 1428 Ping pong
    数学技巧
    UVa 11300 Spreading the Wealth
    UVa 11729 Commando War
    UVa 11292 Dragon of Loowater
    POJ 3627 Bookshelf
    POJ 1056 IMMEDIATE DECODABILITY
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7019684.html
Copyright © 2011-2022 走看看