码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ】3225 线段树 + 离散化 + 区间交并

时间:2015-04-25 19:50:10      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

区间交并的题,感觉好纠结。

先递推覆盖标记 之后递推异或标记

再覆盖一段区间的时候,要把这个区间的异或标记全部清空

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson (pos<<1)
#define rson (pos<<1|1)
const int maxn = 145555;
const int maxd = 145550;
char op[10],cmp[105];
int  a,b;
int  c1[maxn << 2],c2[maxn << 2];
bool vis[maxn] = {0};
void change(int pos){
    if(c1[pos] != -1)
        c1[pos] ^= 1;
    else
        c2[pos] ^= 1;
}
void pushdown(int pos){
    if(c1[pos] != -1){
        c1[lson] = c1[rson] = c1[pos];
        c2[lson] = c2[rson] = 0;
        c1[pos]  = -1;
    }
    if(c2[pos]){
        change(lson);
        change(rson);
        c2[pos] = 0;
    }
}
void update(char op,int L,int R,int l,int r,int pos){
    if(l <= L && R <= r){
        if(op == 'U'){
            c1[pos] = 1;                //改变覆盖标记
            c2[pos] = 0;
        }
        if(op == 'D'){
            c1[pos] = 0;                //改变覆盖标记
            c2[pos] = 0;
        }
        if(op == 'C' || op == 'S'){
            change(pos);
        }
        return;
    }
    pushdown(pos);
    int mid = (L + R) >> 1;
    if(l <= mid) update(op,L,mid,l,r,lson);
    else if(op == 'I' || op == 'C'){
        c2[lson] = c1[lson] = 0;
    }
    if(mid < r) update(op,mid + 1,R,l,r,rson);
    else if(op == 'I' || op == 'C'){
        c2[rson] = c1[rson] = 0;
    }
}
void query(int l,int r,int pos){
    if(c1[pos] == 1){
        for(int i = l; i <= r; i++)
            vis[i] = true;
        return;
    }
    else if(c1[pos] == 0) return;
    if(l == r) return;
    pushdown(pos);
    int mid = (l + r) >> 1;
    query(l,mid,lson);
    query(mid + 1,r,rson);
}
int main(){
    c1[1] = c2[1] = 0;
    while(scanf("%s",&op) != EOF){
        scanf("%s",cmp);
        int L = strlen(cmp),pos;
        sscanf(cmp + 1,"%d",&a);
        pos = strchr(cmp,',') - cmp;
        sscanf(cmp + pos + 1,"%d",&b);
        a <<= 1; b <<= 1;
        if(cmp[0] == '(')     a ++;
        if(cmp[L - 1] == ')') b --;
        if(a > b){
            if(op[0] == 'C' || op[0] == 'I'){
                c1[1] = c2[1] = 0;
            }
        }
        else{
            update(op[0],0,maxd,a,b,1);
        }
    }
    query(0,maxd,1);
    bool flag = false;
    int i;
    for(i = 0; i <= maxd;i++){
        if(vis[i]){
            if(flag) printf(" ");
            if(i & 1)
                printf("(%d,",(i - 1) / 2);
            else
                printf("[%d,", i / 2);
            for(i = i + 1; vis[i]; i++);
            i --;
            if(i & 1)
                printf("%d)",(i + 1) / 2);
            else
                printf("%d]", i / 2);
            flag = true;
        }
    }
    if(!flag) printf("empty set");
    return 0;
}


【POJ】3225 线段树 + 离散化 + 区间交并

标签:

原文地址:http://blog.csdn.net/u013451221/article/details/45272905

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!