Gym - 100513D Data Center 貪心
The startup "Booble" has shown explosive growth and now it needs a new data center with the capacity of m petabytes. Booble can buy servers, there are n servers available for purchase: they have equal price but different capacities. The i-th server can store ai petabytes of data. Also they have different energy consumption — some servers are low voltage and other servers are not.
Booble wants to buy the minimum number of servers with the total capacity of at least m petabytes. If there are many ways to do it Booble wants to choose a way to maximize the number of low voltage servers. Booble doesn't care about exact total capacity, the only requirement is to make it at least m
Input
The first line contains two integer numbers n and m (1 ≤ n ≤ 2·105, 1 ≤ m ≤ 2·1015) — the number of servers and the required total capacity.
The following n lines describe the servers, one server per line. The i-th line contains two integers ai, li (1 ≤ ai ≤ 1010, 0 ≤ li ≤ 1), where a
It is guaranteed that the sum of all ai is at least m.
Output
Print two integers r and w on the first line — the minimum number of servers needed to satisfy the capacity requirement and maximum number of low voltage servers that can be bought in an optimal r servers set.
Print on the second line r distinct integers between 1 and n — the indices of servers to buy. You may print the indices in any order. If there are many solutions, print any of them.
Examples
Input
4 10
3 1
7 0
5 1
4 1
Output
2 1
4 2
Input
3 13
6 1
6 1
6 1
Output
3 3
1 2 3
Note
In the first example any pair of servers which includes the server 2 is a correct output.
題解:先找最少數量,然後再從大往小找是低壓的,去掉已選最小高壓的,判斷當然是否還符合條件
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
typedef long long ll;
using namespace std;
const int N=2e5+10;
struct node{
int id,op;
ll x;
}a[N];
bool vis[N];
bool cmp(node x,node y)
{
if(x.x!=y.x) return x.x>y.x;
else return x.op>y.op;
}
ll n,m;
int main()
{
while(~scanf("%lld%lld",&n,&m))
{
for(int i=1;i<=n;i++)
scanf("%lld%d",&a[i].x,&a[i].op),a[i].id=i,vis[i]=0;
sort(a+1,a+1+n,cmp);
ll ans=0;
int sum1=0,sum2=0;
stack<int> s;
int p;
for(int i=1;i<=n;i++)
{
ans+=a[i].x;
sum1++;
vis[i]=1;
if(a[i].op==1) sum2++;
else
{
s.push(i);
}
if(ans>=m)
{
p=i;
break;
}
}
p++;
while(p<=n&&!s.empty())
{
int now=s.top();s.pop();
while(p<=n&&a[p].op==0)
p++;
if(p>n) break;
if(a[p].x+ans-a[now].x>=m)
{
ans=ans-a[now].x+a[p].x;
vis[now]=0;
vis[p]=1;
sum2++;
p++;
}
else break;
}
printf("%d %d\n",sum1,sum2);
for(int i=1;i<=n;i++)
{
if(vis[i]) printf("%d",a[i].id);
else continue;
sum1--;
if(sum1==0)
{
printf("\n");
break;
}
else printf(" ");
}
}
return 0;
}