POJ 3225 Help with Intervals

本文介绍了一种处理区间操作的方法,通过倍增区间技术解决了区间开闭问题,并结合线段树实现高效的区间覆盖和翻转操作。文章还提供了详细的代码实现。

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

这个题目就两个关键,搞明白就没什么问题:

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互换

2.倍化区间处理开闭区间的问题因为普通的线段树实际处理的并非真正的区间,而是一系列点,相当于处理一个向量这个问题需要处理的是真正的区间,所以应该有一个主导思想就是,把区间点化!不知哪位大牛搞了一个倍增区间出来,实在佩服!对于待处理区间[a,b](暂时不考虑开闭),对其边界均乘2。若区间左开则对左界值+1,若区间右开,则对右界-1!

    如:[2,3]会倍增为[4,6],[2,3)会倍增为[4,5],(2,3]会倍增为[5,6],(2,3)将倍增为[5,5],我们这时可以看到,对于普通线段树无法处理的线段如(x,x+1)将被点化为[2*x+1,2*x+1]!这个问题得到比较完美的解决

最后把查找出来的区间逆向倍增操作一下,就可以得到实际的区间以及起开闭情况!

代码中还将用到延迟更新,向子节点更新操作时,这个具体纠结在互换上面,不过仔细想想还是容易理解的,下面代码会有注解!

区间倍增后,就是处理普通线段树了,这时候一定要思路清晰!

当然普通线段树有两种,1).一种是一开一闭的形式,兄弟节点看上去好像连接起来了(由于开闭是固定的,所以无法直接来处理该题):如对于父节点[a,b),其左孩子为[a,(a+b)/2),右孩子为[(a+b)/2,b)……2).另一种是全闭的形式,对于父节点[a,b],其左孩子为[a,(a+b)/2],右孩子为[(a+b)/2+1,b]……这时候一定要看清本质,不要被倍增区间搞混了!

注:题目中还要处理一些无效输入如(4,4)这种没有意义的区间


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 65536<<2;
int   setv[(MAXN<<2)+1], XOR[(MAXN<<2)+1];
bool  hash[MAXN+10];

void PushDown(int rt)
{
    if(setv[rt] != -1)
    {
        setv[rt<<1] = setv[rt];
        setv[rt<<1|1] = setv[rt];
        XOR[rt<<1] = XOR[rt<<1|1] = 0;
        setv[rt] = -1;
    }
    if(XOR[rt])
    {
        if(setv[rt<<1] != -1)
            setv[rt<<1] ^= 1;
        else
            XOR[rt<<1] ^= 1;

        if(setv[rt<<1|1] != -1)
            setv[rt<<1|1] ^= 1;
        else
            XOR[rt<<1|1] ^= 1;
        XOR[rt] = 0;
    }
    return ;
}

void Bulid(int l, int r, int rt)
{
    setv[rt] = 0;
    XOR[rt] = 0;
    if(l == r) return ;
    int m = (l + r)>>1;
    Bulid(l, m, rt<<1);
    Bulid(m + 1, r, rt<<1|1);
    return ;
}

void Update(char op, int L, int R, int l, int r, int rt)
{
    if(L == l && R == r)
    {
        if(op == 'U')
        {
            setv[rt] = 1;
            XOR[rt] = 0;
        }
        else if(op == 'D')
        {
            setv[rt] = 0;
            XOR[rt] = 0;
        }
        else if(op == 'S')
        {
            if(setv[rt] != -1)
            {

                setv[rt] ^= 1;
            }
            else
            {
                XOR[rt] ^= 1;
            }
        }
        return ;
    }
    PushDown(rt);
    int m = (l + r)>>1;
    if(R <= m)
        Update(op, L, R, l, m, rt<<1);
    else if(L > m)
        Update(op, L, R, m + 1, r, rt<<1|1);
    else
    {
        Update(op, L, m, l, m, rt<<1);
        Update(op, m + 1, R, m + 1, r, rt<<1|1);
    }
    return ;
}

void Query(int l, int r, int rt)
{
    if(setv[rt] >= 0)
    {
        if(setv[rt])
        {
            for(int i = l; i <= r; ++i)
            {
                hash[i] = true;
            }
        }
        return ;
    }
    PushDown(rt);
    int m = (l + r)>>1;
    Query(l, m, rt<<1);
    Query(m + 1, r, rt<<1|1);
    return ;
}

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

    char op, ch1, ch2; int a, b;

    memset(hash, false, sizeof(hash));
    Bulid(1, MAXN, 1);
    while(scanf("%c %c%d,%d%c\n", &op, &ch1, &a, &b, &ch2) != EOF)
    {
        a++, b++;
        a <<= 1, b <<= 1;
        if(ch1 == '(') a++;
        if(ch2 == ')') b--;
        if(op == 'U')
        {
            if(a <= b)
            {
                Update('U', a, b, 1, MAXN, 1);
            }
        }
        else if(op  == 'I')
        {
            if(a - 1 >= 1)
                Update('D', 1, a - 1, 1, MAXN, 1);
            if(b + 1 <= MAXN)
                Update('D', b + 1, MAXN, 1, MAXN, 1);
        }
        else if(op == 'D')
        {
            if(a <= b)
                Update('D', a, b, 1, MAXN, 1);
        }
        else if(op == 'C')
        {
            if(a - 1 >= 1)
                Update('D', 1, a-1, 1, MAXN, 1);
            if(b + 1 <= MAXN)
                Update('D', b + 1, MAXN, 1, MAXN, 1);
            if(a <= b)
                Update('S', a, b, 1, MAXN, 1);
        }
        else if(op == 'S')
        {
            if(a <= b)
                Update('S', a, b, 1, MAXN, 1);
        }
    }
    Query(1, MAXN, 1);
    bool flag = false; int x, y; x = y = -1;
    for(int i = 1; i <= MAXN; ++i)
    {
        if(hash[i])
        {
            if(x == -1)
                x = i;
            else
                y = i;
        }
        else
        {
            if(x != -1)
            {
                if(y == -1) y = x;
                if(flag)
                    printf(" %c%d,%d%c", x&1?'(':'[', x/2-1, (y+1)/2-1, y&1?')':']');
                else
                    printf("%c%d,%d%c", x&1?'(':'[', x/2-1, (y+1)/2-1, y&1?')':']');
                flag = true;
                x = -1; y = -1;
            }
        }
    }
    if(!flag) printf("empty set\n");
    return 0;
}


内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值