宁波多校(三) 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\n"); continue; } int x=query(1,a[i]); printf("%d\n",x); modify(1,x,a[i]); } } return 0; }
没有人不辛苦,只有人不喊疼