宁波多校 G仓鼠的鸡蛋(线段树)

Posted ctyakwf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了宁波多校 G仓鼠的鸡蛋(线段树)相关的知识,希望对你有一定的参考价值。

用线段树维护区间剩余的最大值,这样可以辅助二分,越左越好

对于用完k堆的,直接将他的值变为0即可

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=6e5+10;
struct node{
    int l,r;
    int cnt;
    int k;
}tr[N<<2];
int n,m,k;
int a[N];
void pushup(int u){
    tr[u].cnt=max(tr[u<<1].cnt,tr[u<<1|1].cnt);
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r,m,k};
    }
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int x,int k){
    if(tr[u].l==tr[u].r){
        tr[u].cnt-=k;
        tr[u].k-=1;
        if(tr[u].k==0){
            tr[u].cnt=0;
        }
        return ;
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(x<=mid)
        modify(u<<1,x,k);
    else{
        modify(u<<1|1,x,k);
    }
    pushup(u);
}
int query(int u,int x){
    if(tr[u].l==tr[u].r){
        return tr[u].l;
    }
    int mid=tr[u].r+tr[u].l>>1;
    int res=0;
    if(tr[u<<1].cnt>=x)
        res=query(u<<1,x);
    else{
        res=query(u<<1|1,x);
    }
    return res;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m>>k;
        int i;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        for(i=1;i<=n;i++){
            if(a[i]>tr[1].cnt){
                printf("-1
");
                continue;
            }
            int x=query(1,a[i]);
            printf("%d
",x);
            modify(1,x,a[i]);
        }
    }
    return 0;
}
View Code

 

以上是关于宁波多校 G仓鼠的鸡蛋(线段树)的主要内容,如果未能解决你的问题,请参考以下文章

宁波多校 D题 COLORS的字符串挑战(线段树+hash+二分)

宁波多校 C石头划分(二分)

2019杭电多校第六场hdu6638 Snowy Smile(线段树+枚举)

2019杭电多校第三次hdu6609 Find the answer(线段树)

2018多校第十场 HDU 6430 线段树合并

2022杭电多校 DOS Card(线段树)