zoukankan      html  css  js  c++  java
  • POJ 3225 Help with Intervals(线段树)

      这题纠结了两天,开始一点思路没有,后来看到有大牛把这题的做法称作区间树,并说明了区间树与线段树的区别(区间树是区间内被染色的区间标记为1,未被染色的区间标记为0)。我觉得这就是线段树的一类操作,没有必要分出去吧。。。

    思路:区间更新,首先想到的应该是Lazy思想;这题分五种情况:

    CommandSemantics
    U T S  S  T
    I T S  S  T
    D T S  S  T
    C T S  T  S
    S T S  S  T

    U:直接将T对应的区间覆盖为1;

    I:将T的补区间(比如T[l, r], 补区间就是[0, l-1], [r+1, N])清零即可;

    D:直接将T区间清零;

    C:先将T的补区间清零,再对T区间取反;

    S:直接对T区间取反;

    (把这几个操作在纸上写写,马上就明白了。)

    然后就是剩下的线段树的区间更新、区间上传、区间下分了。

    Code:

    #include <iostream>
    #include
    <cstdio>
    #include
    <cstring>
    #define L(t) t << 1
    #define R(t) t << 1 | 1
    using namespace std;

    const int N = 65540*2;

    class node{
    public:
    int l, r;
    int cov;
    int change; //表示该区间是否需要被改变;
    void changeEdit(){ //按change进行操作
    if(change) change = 0; //如果需要改变,当前区间标为不需要
    else if(cov != -1) cov ^= 1; //如果当前段非单色, 对他进行^改变
    else change = 1;
    }
    }node[N
    *4];

    int flag[N];

    // 下分
    void PushDown(int t){
    if(node[t].cov != -1){
    node[L(t)].cov
    = node[R(t)].cov = node[t].cov;
    node[L(t)].change
    = node[R(t)].change = node[t].change;
    }
    if(node[t].change){
    node[L(t)].changeEdit();
    node[R(t)].changeEdit();
    node[t].change
    = 0;
    }
    }
    //上传
    void PushUp(int t){
    if(node[L(t)].cov == node[R(t)].cov){
    node[t].cov
    = node[L(t)].cov;
    }
    else {
    node[t].cov
    = -1;
    }
    }

    void creat(int t, int l, int r){
    node[t].l
    = l;
    node[t].r
    = r;
    node[t].cov
    = 0;
    node[t].change
    = 0;

    if(l == r) return ;

    int mid = (l + r) >> 1;

    creat(L(t), l, mid);
    creat(R(t), mid
    +1, r);
    }

    void updata(int t, int l, int r, int v){
    if(node[t].l > l || node[t].r < r) return ;

    if(node[t].l >= l && node[t].r <= r){
    //printf("%d %d %d\n", l, r, v);
    node[t].cov = v;
    node[t].change
    = 0;
    return ;
    }

    PushDown(t);
    int mid = (node[t].l + node[t].r) >> 1;

    if(l > mid)
    updata(R(t), l, r, v);
    else if(r <= mid)
    updata(L(t), l, r, v);
    else{
    updata(L(t), l, mid, v);
    updata(R(t), mid
    +1, r, v);
    }
    PushUp(t);
    }

    void XOR(int t, int l, int r){
    if(node[t].l > l || node[t].r < r) return ;

    if(node[t].l == l && node[t].r == r){
    //printf("%d %d %d\n", l, r, node[t].cov);
    if(node[t].cov != -1)
    node[t].cov
    ^= 1;
    else
    node[t].change
    ^= 1;
    return ;
    }

    PushDown(t);
    int mid = (node[t].l + node[t].r) >> 1;

    if(l > mid)
    XOR(R(t), l, r);
    else if(r <= mid)
    XOR(L(t), l, r);
    else{
    XOR(L(t), l, mid);
    XOR(R(t), mid
    + 1, r);
    }
    PushUp(t);
    }

    void query(int t){
    if(node[t].l == node[t].r){
    flag[node[t].l]
    = node[t].cov;
    return ;
    }
    PushDown(t);
    query(L(t));
    query(R(t));
    }

    int main(){
    //freopen("data.in", "r", stdin);

    int l, r, i;
    char s, p, q;

    creat(
    1, 0, N);

    while(~scanf("%c %c%d,%d%c\n", &s, &p, &l, &r, &q)){
    l
    *= 2; r *= 2;
    if(p == '(') l++;
    if(q == ')') r--;

    if(s == 'U'){
    updata(
    1, l, r, 1);
    }
    else if(s == 'I'){
    if(l > 0)
    updata(
    1, 0, l - 1, 0);
    if(r < N)
    updata(
    1, r + 1, N, 0);
    }
    else if(s == 'D'){
    updata(
    1, l, r, 0);
    }
    else if(s == 'C'){
    if(l > 0)
    updata(
    1, 0, l - 1, 0);
    if(r < N)
    updata(
    1, r + 1, N, 0);
    XOR(
    1, l, r);
    }
    else{
    XOR(
    1, l, r);
    }
    }
    query(
    1);
    int begin, end, tmp = 1;
    for(i = 0; i <= N; i++){
    while(i <= N && !flag[i]) i++;
    begin
    = i;
    if(i > N) break;

    while(i <= N && flag[i]) i++;
    end
    = i - 1;

    tmp
    = 0;

    if(begin&1){
    printf(
    "(%d,", begin/2);
    }
    else{
    printf(
    "[%d,", begin/2);
    }

    if(end&1){
    printf(
    "%d) ", (end+1)/2);
    }
    else{
    printf(
    "%d] ", end/2);
    }
    }
    if(tmp)
    printf(
    "empty set");
    putchar(
    '\n');
    return 0;
    }
  • 相关阅读:
    Asp.Net细节性问题精萃(转)
    开发OFFICE插件总结(转)
    校内网开心网数据同步引发的讨论(转)
    C++指针探讨 (三) 成员函数指针 (转)
    C++指针探讨 (二) 函数指针 (转)
    【原创】编程获取PE文件信息的方法(转)
    为.net开发者提供的一份关于存储过程的评论(转)
    C++指针探讨 (一)数据指针 (转)
    如何批量修改PPT字体、大小、颜色(转)
    搜索引擎里的爱人(转)
  • 原文地址:https://www.cnblogs.com/vongang/p/2182900.html
Copyright © 2011-2022 走看看