链接:点击打开链接
题意:给你一个长度为的数组和一个
,求出对每一个
最少删除
~
中多少个元素,使得剩余的
~
中的元素的和小于等于
代码:
#include <map>
#include <set>
#include <queue>
#include <string>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int siz=2*100005;
map<int,int> mp;
int n,a[siz];
long long sum[siz],num[siz];
struct node{
int u,id;
friend bool operator<(node a,node b){
if(a.u==b.u)
return a.id<b.id;
return a.u<b.u;
}
};
vector<node> G;
int lowbit(int x){
return x&(-x);
}
void update(int x,int y){
while(x<=n){
num[x]++;
sum[x]+=y;
x+=lowbit(x);
}
}
long long query_sum(int x){
long long ans=0;
while(x>0){
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
long long query_num(int x){
long long ans=0;
while(x>0){
ans+=num[x];
x-=lowbit(x);
}
return ans;
}
int main(){
int i,j,u,t,l,r,ans,mid;
long long m,tmp;
scanf("%d",&t);
while(t--){ //sum按zhi值维护前缀和,num按个数维护前缀和
scanf("%d%lld",&n,&m);
memset(sum,0,sizeof(sum));
memset(num,0,sizeof(num));
G.clear();
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
G.push_back((node){a[i],i});
}
sort(G.begin(),G.end());
for(i=0;i<G.size();i++)
mp[G[i].id]=i+1;
for(i=1;i<=n;i++){ //每次二分出最长小于等于m-当前值的最长前缀的长度
ans=0; //算出当前前缀中所含元素的个数
l=1,r=n,tmp=m-a[i];
while(l<=r){
mid=(l+r)>>1;
if(query_sum(mid)<=tmp){
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%d ",i-1-query_num(ans));
update(mp[i],a[i]);
}
printf("\n");
}
return 0;
}
/*
2
5 10
10 10 10 10 10
*/