POJ - 3667(线段树区间合并)

poj3667

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=50005;
struct node{
    int l;//区间的左端点
    int r;//区间的右端点
    int sum;//该区间的最长空闲区间的长度
    int lsum;//从该区间的左端点起,最长的空闲区间长度
    int rsum;//从该区间的右端点起,最长的空闲区间的长度
    int cov;//cov=-1时表示该区间不能向下pushdown,cov=1时表示该区间已经全部填满,cov=0时表示该区间全部为空闲区
}tree[maxn<<2];
void build(int m,int l,int r)
{
   int mid=(l+r)>>1;
   tree[m].l=l;
   tree[m].r=r;
   tree[m].sum=r-l+1;
   tree[m].lsum=r-l+1;
   tree[m].rsum=r-l+1;
   tree[m].cov=-1;
   if(l==r){
    return ;
   }
   build(m<<1,l,mid);
   build(m<<1|1,mid+1,r);
}
void pushdown(int m)
{
    if(tree[m].cov==-1)return ;
    tree[m<<1].cov=tree[m<<1|1].cov=tree[m].cov;
    if(tree[m].cov==1){
        tree[m<<1].sum=tree[m<<1].lsum=tree[m<<1].rsum=0;
        tree[m<<1|1].sum=tree[m<<1|1].lsum=tree[m<<1|1].rsum=0;
    }
    else{
        tree[m<<1].sum=tree[m<<1].lsum=tree[m<<1].rsum=tree[m<<1].r-tree[m<<1].l+1;
        tree[m<<1|1].sum=tree[m<<1|1].lsum=tree[m<<1|1].rsum=tree[m<<1|1].r-tree[m<<1|1].l+1;
    }
    tree[m].cov=-1;
}
void pushup(int m,int l,int r)
{
    tree[m].lsum=tree[m<<1].lsum;
    tree[m].rsum=tree[m<<1|1].rsum;
    int mid=(l+r)>>1;
    if(tree[m].lsum==mid-l+1)tree[m].lsum+=tree[m<<1|1].lsum;
    if(tree[m].rsum==r-mid)tree[m].rsum+=tree[m<<1].rsum;
    tree[m].sum=max(max(tree[m<<1].sum,tree[m<<1|1].sum),tree[m<<1].rsum+tree[m<<1|1].lsum);
}
int query(int m,int l,int r,int p)
{
    //printf("%d %d\n",l,r);
    if(l==r){
        return l;
    }
    pushdown(m);//如果当前还没查询到所要的区间,就要及时pushdown,因为这样会节约一些不必要的操作
                //只有该区间的cov值为0或则为1时,才会向左右子区间下压,
    int mid=(l+r)>>1;
    if(tree[m<<1].sum>=p)return query(m<<1,l,mid,p);
    else
        if(tree[m<<1].rsum+tree[m<<1|1].lsum>=p)
            return mid-tree[m<<1].rsum+1;
    else
        return query(m<<1|1,mid+1,r,p);
}
void update(int m,int l,int r,int p)
{
    //printf("%d %d\n",tree[m].l,tree[m].r);
    if(tree[m].l>=l&&tree[m].r<=r){
            //printf("%d %d\n",tree[m].l,tree[m].r);
        tree[m].cov=p;
        if(p==1){
            tree[m].sum=tree[m].lsum=tree[m].rsum=0;
        }
        else{
            tree[m].sum=tree[m].lsum=tree[m].rsum=tree[m].r-tree[m].l+1;
        }
        return ;
    }
    pushdown(m);//更新时也不要忘记向下pushdown
    int mid=(tree[m].l+tree[m].r)>>1;
    if(l<=mid)
        update(m<<1,l,r,p);
    if(r>mid)
        update(m<<1|1,l,r,p);
    pushup(m,tree[m].l,tree[m].r);//向上更新父节点区间的lsum,sum,rsum,但不能对父节点的cov值进行操作
}                                 //因为你不能保证左右子节点区间的cov的值相同且不为-1
int n,m;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
    build(1,1,n);
    while(m--){
            /*for(int i=1;i<=4*n;i++){
                printf("%d %d %d\n",tree[i].sum,tree[i].lsum,tree[i].rsum);
            }*/
        int op;
        scanf("%d",&op);
        if(op==1){
            int x;
            scanf("%d",&x);
            if(tree[1].sum<x){
                printf("0\n");
                continue;
            }
            else{
                int tmp=query(1,1,n,x);
                printf("%d\n",tmp);
                //printf("%d %d\n",tmp,tmp+x-1);
                update(1,tmp,x+tmp-1,1);
            }
        }
        else{
            int a,b;
            scanf("%d%d",&a,&b);
            update(1,a,a+b-1,0);
        }
        //printf("okkkk\n");
    }
    }
    return 0;
}
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值