题目描述
小路绫 (Komichi Aya) 想要给阳子 (Inokuma Youko) 做便当。
小路绫现在有n种食材,编号从1到n,她会按编号顺序放入这n种食材。
对于每种食材阳子有一个美味度ai。
小路绫知道,对于所有1≤i≤n,设前i种食材的美味度总和。
当加入第i种食材时,如果si>m,阳子就会吃撑。
所以小路绫每放入一种食材时,都会想知道:最少要从之前已经选过的食材中去掉多少食材,才不会让阳子吃撑。
当然,小路绫不会真正地把食材去掉,她只是想知道结果而已。才不是关心你呢!
输入
第一行为两个正整数n,m,分别表示食材的种类数以及会使阳子吃撑的值m。
接下来为一行n个正整数,其中第i个正整数表示ai。
输出
输出一行n个非负整数,其中第i个非负整数表示在加入第i种食材时,至少要去掉之前加入的多少种食材才能不让阳子吃撑。
样例输入
【样例1】
7 15
1 2 3 4 5 6 7
【样例2】
5 100
80 40 40 40 60
样例输出
【样例1】
0 0 0 0 0 2 3
【样例2】
0 1 1 2 3
提示
思路
树状数组维护[1,i-1]区间内前k小的值的和sk,每次询问二分找最大k值使得sk+当前值<=m,i-k-1即为答案
代码实现
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define re register
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e6+5;
const int M=5e6+5;
const int INF=0x3f3f3f3f;
const ll LINF=1e18;
const ull sed=31;
const ll mod=1e9+7;
// const double eps=1e-6;
// const double PI=acos(-1.0);
// const double delta=0.993;
typedef pair<int,int>P;
typedef pair<double,double>Pd;
typedef pair<ll,int> plt;
typedef pair<ll,ll> pll;
template<class T>inline void read(T &x)
{
x=0;int f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
template<class T>inline void write(T x)
{
if (x < 0) x = ~x + 1, putchar('-');
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
struct node
{
int id,val,rk;
}E[N];
ll T1[N],T2[N];
int n,m;
inline int lowbit(int x) {return x&(-x);}
void add(int x,ll p)
{
for(;x<=n;x+=lowbit(x))
{
T1[x]+=p;
T2[x]++;
}
}
int sum(int x)
{
int tot=0;
for(;x;x-=lowbit(x)) tot+=T2[x];
return tot;
}
ll query(int x)
{
ll tot=0;
for(;x;x-=lowbit(x)) tot+=T1[x];
return tot;
}
bool cmp1(node a,node b)
{
return a.val<b.val;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int main()
{
// freopen("a.txt","r",stdin);
read(n);read(m);
for(int i=1;i<=n;i++)
{
read(E[i].val);
E[i].id=i;
}
sort(E+1,E+1+n,cmp1);
for(int i=1;i<=n;i++) E[i].rk=i;
sort(E+1,E+1+n,cmp2);
for(int i=1;i<=n;i++)
{
if(i-1) putchar(' ');
int l=1,r=n,ans=0;
while (l<=r)
{
int mid=(l+r)>>1;
if(query(mid)+E[i].val<=m)
{
ans=max(ans,mid);
l=mid+1;
}
else r=mid-1;
}
printf("%d",i-sum(ans)-1);
add(E[i].rk,E[i].val);
}
puts("");
return 0;
}