POJ 3225(线段树)
Posted starry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3225(线段树)相关的知识,希望对你有一定的参考价值。
POJ 3225
题 意 : 区 间 操 作 , 交 , 并 , 补 等
思 路 :
我 们 一 个 一 个 操 作 来 分 析 :( 用 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 就 可 以 处 理 ( 偶 数 表 示 端 点 , 奇 数 表 示 两 端 点 间 的 区 间 ) 线 段 树 功 能 :
u p d a t e : 成 段 替 换 ,区 间 异 或 q u e r y : 简 单 h a s h
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 using namespace std; 7 const int MAX = 65555*2; 8 bool Hash[MAX]; 9 int cover[MAX<<2], XOR[MAX<<2]; 10 void FXOR(int rt){ 11 if(cover[rt] != -1)cover[rt]^=1; 12 else XOR[rt] ^= 1; 13 } 14 void PushDown(int rt){ 15 if(cover[rt] != -1){ 16 cover[rt<<1] = cover[rt<<1|1] = cover[rt]; 17 XOR[rt<<1] = XOR[rt<<1|1] = 0; 18 cover[rt] = -1; 19 } 20 if(XOR[rt]){ 21 FXOR(rt<<1); 22 FXOR(rt<<1|1); 23 XOR[rt] = 0; 24 } 25 } 26 void update(char op, int LL, int RR, int l, int r, int rt){ 27 if(LL <= l && r <= RR){ 28 if(op == ‘U‘){ 29 cover[rt] = 1; 30 XOR[rt] = 0; 31 }else if(op == ‘D‘){ 32 cover[rt] = 0; 33 XOR[rt] = 0; 34 }else if(op == ‘C‘ || op == ‘S‘){ 35 FXOR(rt); 36 } 37 return; 38 } 39 PushDown(rt); 40 int m = (l+r)>>1; 41 if(LL <= m)update(op,LL,RR,lson); 42 else if(op == ‘I‘ || op == ‘C‘){ 43 XOR[rt<<1] = cover[rt<<1] = 0; 44 } 45 if(m < RR)update(op,LL,RR,rson); 46 else if(op == ‘I‘ || op == ‘C‘){ 47 XOR[rt<<1|1] = cover[rt<<1|1] = 0; 48 } 49 } 50 void query(int l, int r, int rt){ 51 if(cover[rt] == 1){ 52 for(int it = l; it <= r; it++){ 53 Hash[it] = true; 54 } 55 return; 56 }else if(cover[rt] == 0)return; 57 if(l == r) return; 58 PushDown(rt); 59 int m = (l+r)>>1; 60 query(lson); 61 query(rson); 62 } 63 int main(){ 64 cover[1] = XOR[1] = 0; 65 char op, l, r; 66 int a, b; 67 while(~scanf("%c %c%d,%d%c\n",&op,&l,&a,&b,&r)){ 68 a<<=1, b<<=1; 69 if(l == ‘(‘)a++; 70 if(r == ‘)‘)b--; 71 if(a > b){ 72 if(op==‘C‘ || op == ‘I‘){ 73 cover[1] = XOR[1] = 0; 74 } 75 }else update(op,a,b,0,MAX,1); 76 } 77 query(0,MAX,1); 78 bool flag = false; 79 int s = -1,e; 80 for(int i = 0; i <= MAX; i ++){ 81 if(Hash[i]){ 82 if(s == -1)s=i; 83 e =i; 84 }else{ 85 if(s != -1){ 86 if(flag)printf(" "); 87 flag = true; 88 printf("%c%d,%d%c",s&1?‘(‘:‘[‘,s>>1,(e+1)>>1,e&1?‘)‘:‘]‘); 89 s=-1; 90 } 91 } 92 } 93 if(!flag)printf("empty set"); 94 return 0; 95 }
以上是关于POJ 3225(线段树)的主要内容,如果未能解决你的问题,请参考以下文章