主席树

主席树+离散

1.利用前缀和性质,建立n棵权值线段树(1-i区间内有几个数离散化后的值在树上每个结点对应区间内)

2.查询i到j区间只需将第j棵树减去第i-1棵树,得到表示i到j区间内情况的树,线段树查询即可。

建树O(nlogn),查询每次O(logn)

注意:待修主席树为了修改方便(和建树共用一个函数),开点时常用if(!rt) rt=con-1;这样修改的时候不会新开节点。

           但是主席树建树每个rt必须开新的结点,不能有 if(!rt) ,因为tree[con++]=tree[rt],如果不开新节点,之前的结点会被修改。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,con=1,rt[100010],num[100010],p[100010];
struct node
{
    int l,r,sum;
}tree[100010*20];
void build(int l,int r,int &rt,int num)
{
    tree[con++]=tree[rt];
    rt=con-1;
    tree[rt].sum++;
    if(l==r)
    {
        return;
    }
    int mid=(l+r)>>1;
    if(num<=mid)
    build(l,mid,tree[rt].l,num);
    else
    build(mid+1,r,tree[rt].r,num);
}
int query(int l,int r,int nowq,int nowh,int k)
{
    if(l==r)
    return l;
    int c=tree[tree[nowq].l].sum-tree[tree[nowh].l].sum,mid=(l+r)>>1;
    if(k<=c)
        query(l,mid,tree[nowq].l,tree[nowh].l,k);
    else
        query(mid+1,r,tree[nowq].r,tree[nowh].r,k-c);
}
int main()
{
   // freopen("1.txt","r",stdin);
    int m;
    cin>>n>>m;
    rt[0]=0;
    tree[0].l=tree[0].r=tree[0].sum=0;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&num[i]);
        p[i]=num[i];
    }
    sort(p+1,p+n+1);
    int ed=unique(p+1,p+n+1)-p;
    for(int i=1;i<=n;++i)
    {
        int mid=lower_bound(p+1,p+ed,num[i])-p;
        rt[i]=rt[i-1];
        build(1,n,rt[i],mid);
    }
    while(m--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
       // cout<<query(1,n,rt[b],rt[a-1],c)-1<<endl;
        printf("%d\n",p[query(1,n,rt[b],rt[a-1],c)]);
    }
  /*  for(int i=0;i<=n;++i)
        cout<<rt[i]<<endl;*/
    return 0;
}

  带修主席树

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
struct node
{
    int l,r,v;
}tree[N*400];
int rt[N],con=1,dis[N*2],num[N],n,q[N],h[N],iq,ih,cnt=0,ed;
struct OP
{
    int a,b,c,d;
}op[N];
inline int lowbit(int &x)
{return x&(-x);}
void add(int l,int r,int &now,int x,int z)
{
    if(!now)
    now=con++;
    tree[now].v+=z;
    if(l==r)
    return;
    int mid=(l+r)>>1;
    if(x<=mid)
    add(l,mid,tree[now].l,x,z);
    else
    add(mid+1,r,tree[now].r,x,z);
}
void change(int x,int y,int z)
{
    while(x<=n)
    {
        add(1,ed-1,rt[x],y,z);
        x+=lowbit(x);
    }
}
int sc(int l,int r,int k)
{
    if(l==r)
    return l;
    int mid=(l+r)>>1;
    int s1=0,s2=0;
    for(int i=0;i<iq;++i)
        s1+=tree[tree[q[i]].l].v;
    for(int i=0;i<ih;++i)
        s2+=tree[tree[h[i]].l].v;
   // cout<<l<<' '<<mid<<' '<<s2-s1<<' '<<k<<endl;
    if(s2-s1>=k)
    {
        for(int i=0;i<iq;++i)
        q[i]=tree[q[i]].l;
        for(int i=0;i<ih;++i)
        h[i]=tree[h[i]].l;
        return sc(l,mid,k);
    }
    else
    {
        for(int i=0;i<iq;++i)
        q[i]=tree[q[i]].r;
        for(int i=0;i<ih;++i)
        h[i]=tree[h[i]].r;
        return sc(mid+1,r,k-(s2-s1));
    }
}
int query(int l,int r,int k)
{
    iq=ih=0;
    while(l>=1)
    {
        q[iq++]=rt[l];
        l-=lowbit(l);
    }
    while(r>=1)
    {
        h[ih++]=rt[r];
        r-=lowbit(r);
    }
    return sc(1,ed-1,k);
}
int main()
{
   // freopen("1.txt","r",stdin);
    int m;cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&num[i]);
        dis[i]=num[i];
    }
    cnt=n+1;
    for(int i=0;i<m;++i)
    {
        char s[12];
        scanf("%s",s);
        if(s[0]=='Q')
        {
            scanf("%d%d%d",&op[i].a,&op[i].b,&op[i].c);
            op[i].d=1;
        }
        else
        {
            scanf("%d%d",&op[i].a,&op[i].b);
            op[i].d=0;
            dis[cnt++]=op[i].b;
        }
    }
    sort(dis+1,dis+cnt);
    ed=unique(dis+1,dis+cnt)-dis;
    for(int i=1;i<=n;++i)
    {
        int tmp=lower_bound(dis+1,dis+ed,num[i])-dis;
        num[i]=tmp;
        change(i,tmp,1);
    }
    for(int i=0;i<m;++i)
    {
        if(op[i].d==1)
        {
            printf("%d\n",dis[query(op[i].a-1,op[i].b,op[i].c)]);
        }
        else
        {
            change(op[i].a,num[op[i].a],-1);
            int tmp=lower_bound(dis+1,dis+ed,op[i].b)-dis;
            change(op[i].a,tmp,1);
            num[op[i].a]=tmp;
        }
    }
    return 0;
}

 

内容概要:本文介绍了一个基于冠豪猪优化算法(CPO)的无人机三维路径规划项目,利用Python实现了在复杂三维环境中为无人机规划安全、高效、低能耗飞行路径的完整解决方案。项目涵盖空间环境建模、无人机动力学约束、路径编码、多目标代价函数设计以及CPO算法的核心实现。通过体素网格建模、动态障碍物处理、路径平滑技术和多约束融合机制,系统能够在高维、密集障碍环境下快速搜索出满足飞行可行性、安全性与能效最优的路径,并支持在线重规划以适应动态环境变化。文中还提供了关键模块的代码示例,包括环境建模、路径评估和CPO优化流程。; 适合人群:具备一定Python编程基础和优化算法基础知识,从事无人机、智能机器人、路径规划或智能优化算法研究的相关科研人员与工程技术人员,尤其适合研究生及有一定工作经验的研发工程师。; 使用场景及目标:①应用于复杂三维环境下的无人机自导航与避障;②研究智能优化算法(如CPO)在路径规划中的实际部署与性能优化;③实现多目标(路径最短、能耗最低、安全性最高)耦合条件下的工程化路径求解;④构建可扩展的智能无人系统决策框架。; 阅读建议:建议结合文中模型架构与代码示例进行实践运行,重点关注目标函数设计、CPO算法改进策略与约束处理机制,宜在仿真环境中测试不同场景以深入理解算法行为与系统鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值