51nod1287【线段树+折半搜索】

本文介绍了一种利用线段树维护区间最大值,并结合二分查找解决问题的方法。通过具体的代码实现展示了如何在数组中高效地进行查找、更新操作。

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

思路:

其实就是每次折半找一下对吧,但是要维护出一个区间最(大)值,所以套一个线段树就可以轻松解决了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

const int INF=0x3f3f3f3f;
const int N=5e4+10;
struct asd{
    int Left,Right;
    int val;
}node[N<<2];
void Build(int num,int Left,int Right){
    node[num].Left = Left;
    node[num].Right = Right;
    if(Left == Right){
        scanf("%d",&node[num].val);
        return;
    }
    int Mid=(Left+Right)>>1;
    Build(num<<1,Left,Mid);
    Build(num<<1|1,Mid+1,Right);
    node[num].val=max(node[num<<1].val,node[num<<1|1].val);
}

int DFS(int num,int val){
    if(node[num].val<val) return INF;
    if(node[num].Left == node[num].Right)
        return node[num].Left;
    if(node[num<<1].val>=val)
        return DFS(num<<1,val);
    else
        return DFS(num<<1|1,val);
}

void ADD(int num,int s)
{
    if(node[num].Left == node[num].Right && node[num].Left == s){
        node[num].val++;
        return;
    }
    int Mid=(node[num].Left+node[num].Right)>>1;
    if(Mid>=s)
        ADD(num<<1,s);
    else
        ADD(num<<1|1,s);
    node[num].val=max(node[num<<1].val,node[num<<1|1].val);
}

int query(int num,int s)
{
    if(node[num].Left == node[num].Right && node[num].Left == s)
        return node[num].val;
    int Mid=(node[num].Left+node[num].Right)>>1;
    if(Mid>=s)
        return query(num<<1,s);
    else
        return query(num<<1|1,s);
}

int main()
{
    int n,m,x,pos;
    scanf("%d%d",&n,&m);
    Build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        pos=DFS(1,x);
        if(pos==1||pos==INF) continue;
        ADD(1,pos-1);
    }
    for(int i=1;i<=n;i++)
        printf("%d\n",query(1,i));
    return 0;
}

/*
9 11
1 2 0 4 3 2 1 5 7
2 8 0 7 6 5 3 4 5 6 5
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值