题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609
题目大意:
思路一:
给出一组数,对于每个数a[i]a[i]a[i]求出最少删除 iii 前面多少个数使得前缀和小于等于mmm。
题解:权值线段树维护以iii为右端点的前缀和以及数的个数。 每次查询最多可以取多少个数可以使得前缀和小于等于mmm,假设为cntcntcnt, 那么最后的答案就是 i−1−cnti-1-cnti−1−cnt
思路二:
模拟判断,然后把当前值插入,再while()把不合法的直接删除,因为当前这个数不合法以后就不会用了。
思路一:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int a[200005], b[200005];
struct NODE
{
int L, R, num;
LL w;
}node[800005];
void BT(int i, int L, int R)
{
node[i].L=L, node[i].R=R;
node[i].num=0, node[i].w=0;
if(L==R)
{
return ;
}
BT(i<<1, L, (L+R)/2);
BT((i<<1)+1, (L+R)/2+1, R);
}
void UP(int i, int x)
{
if(node[i].L==node[i].R)
{
node[i].num++;
node[i].w+=a[x];
return ;
}
if(x<=(node[i].L+node[i].R)/2)
{
UP(i<<1, x);
}
else
{
UP((i<<1)+1, x);
}
node[i].num=node[i<<1].num+node[(i<<1)+1].num;
node[i].w=node[i<<1].w+node[(i<<1)+1].w;
}
int cx(int i, int k)
{
if(node[i].w<=k)
{
return node[i].num;
}
if(node[i].L==node[i].R)
{
return min(node[i].num, k/a[node[i].L]);
}
if(node[i<<1].w>=k)
{
return cx(i<<1, k);
}
else
{
return node[i<<1].num+cx((i<<1)+1, k-node[i<<1].w);
}
}
map<int, int> mp;
int main()
{
int q;
scanf("%d", &q);
while(q--)
{
mp.clear();
int n, m, tot=1;
scanf("%d%d",&n,&m);
BT(1, 1, n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
mp[a[i]]=1;
}
for(map<int, int>::iterator p=mp.begin(); p!=mp.end(); p++)
{
p->second=tot++;
a[p->second]=p->first;
}
for(int i=1;i<=n;i++)
{
printf("%d ", i-cx(1, m-b[i])-1);
UP(1, mp[b[i]]);
}
printf("\n");
}
return 0;
}
思路二:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
multiset<int> s;
LL sum=0;
void er(LL v)
{
s.erase(s.find(v));
sum-=v;
}
void in(LL v)
{
s.insert(v);
sum+=v;
}
int main()
{
int q;
scanf("%d", &q);
while(q--)
{
sum=0;
s.clear();
int n, m, tot=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x, num=0;
scanf("%d", &x);
multiset<int>::iterator it=s.end();
LL tp=sum;
while(tp+x>m)
{
it--;
tp-=(*it);
num++;
}
printf("%d ", num+tot);
in(x);
while(sum>m)
{
multiset<int>::iterator it=s.end();
it--;
er((*it));
tot++;
}
}
printf("\n");
}
return 0;
}