poj 3225 线段树1,0互变 全变0全变1模板

本文介绍了一种基于区间树的数据结构实现,支持区间更新及区间翻转操作,并能高效处理区间查询请求。通过实例演示了如何利用该算法解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

区间更新 当这区间值相同时翻转记录清0因为此时值固定翻转无效了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<queue>
#define lson i<<1
#define rson (i<<1)+1
#define maxn 70000*2
using namespace std;
int flag[maxn * 4], flagX[maxn * 4];// flag 记录01 flagX记录翻转
int ve[maxn], len = 0;
void  pushDown(int i)
{
      if(flag[i]!=-1)
      {
          flag[lson] = flag[i];
          flag[rson] = flag[i];
          flagX[lson] = 0;
          flagX[rson] = 0;
          flagX[i] = 0;
      }
      else
      {
          if(flagX[i])
          {
            if(flag[lson] !=  -1) flag[lson] ^= 1;
            if(flag[rson] !=  -1) flag[rson] ^= 1;
          }
          flagX[lson] ^= flagX[i];
          flagX[rson] ^= flagX[i];
          flagX[i] = 0;
      }
}
void pushUp(int i)
{
      if(flag[lson] == flag[rson] && flag[lson] != -1 ){
         flag[i] = flag[lson];
         flagX[i] = 0;
      }
      else flag[i] = -1;
}
void updateSubAdd(int i,int l,int r,int L,int R,int sym)// sym 为00,为11
{
    // if(flag[i] == sym) return;
     if( l == L && r == R)
     {
        flag[i] = sym;
        flagX[i] = 0;
        return;
     }
     pushDown(i);
     int mid = (l+r)/2;
     if(R <= mid) updateSubAdd(lson, l, mid, L, R, sym);
     else if(L > mid) updateSubAdd(rson, mid + 1, r, L, R, sym);
     else {
         updateSubAdd(lson, l, mid, L, mid, sym);
         updateSubAdd(rson, mid + 1, r, mid + 1, R, sym);
     }
     pushUp(i);
}
void updateXor(int i,int l,int r,int L,int R) //翻转
{
     if(L<= l && R>= r)
     {
        if(flag[i]!=-1)
        {
            flag[i] ^= 1;
            flagX[i] = 0;
        }
        else flagX[i] ^= 1;
        return;
     }
     pushDown(i);
     int mid = (l+r)/2;
     if(R <= mid) updateXor(lson, l, mid, L, R);
     else if(L > mid) updateXor(rson, mid + 1, r, L, R);
     else {
         updateXor(lson, l, mid, L, mid);
         updateXor(rson, mid + 1, r, mid + 1, R);
     }
     pushUp(i);
}
void query(int i, int l, int r)
{
     if(flag[i]!=-1)
     {
         if(flag[i])
         for(int j = l; j <= r; j++) ve[len++] = j;
         return ;
     }
     pushDown(i);
     int mid = (l + r) / 2;
     query(lson, l, mid);
     query(rson, mid + 1, r);
     pushUp(i);
}
void answer()
{
    len = 0;
    query(1, 0, 65537*2);
    if(len == 0) printf("empty set\n");
    else {
        int pre = ve[0];
        if(pre%2)printf("(");
        else printf("[");
        printf("%d",pre/2);
        for(int i = 1; i < len; i++)
            if(ve[i]-ve[i-1]!=1)
            {
               if(pre%2)printf(",%d)",(pre+1)/2);
               else printf(",%d]",(pre+1)/2);
               pre = ve[i];
               printf(" ");
               if(pre%2)printf("(");
               else printf("[");
               printf("%d",pre/2);
            }
            else{
                pre = ve[i];
            }
        if(pre%2)printf(",%d)",(pre+1)/2);
        else printf(",%d]",(pre+1)/2);
        printf("\n");
    }
}
int main()
{
    char q[10];
    while(scanf("%s", q) != EOF)
    {
        char left, right;
        int a, b;
        scanf(" %c%d,%d%c", &left, &a, &b, &right);
        a*=2;
        b*=2;
        if(left == '(') a++;
        if(right == ')') b--;
        if(q[0] == 'U') { if(a<=b)updateSubAdd(1, 0, 65537*2, a, b, 1);}
        else if(q[0] == 'I')
        {
             if(0<=a-1)updateSubAdd(1, 0, 65537*2, 0, a-1, 0);
             if(b+1<=65537*2)updateSubAdd(1, 0, 65537*2, b+1, 65537*2, 0);
        }
        else if(q[0] == 'D') { if(a<=b)updateSubAdd(1, 0, 65537*2, a, b, 0);}
        else if(q[0] == 'C')
        {
             if(a<=b)updateXor(1, 0, 65537*2, a, b);
             if(0<=a-1)updateSubAdd(1, 0, 65537*2, 0, a-1, 0);
             if(b+1<=65537*2)updateSubAdd(1, 0, 65537*2, b+1, 65537*2, 0);
        }
        else if(a<=b) updateXor(1, 0, 65537*2, a, b);

    }
    answer();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值