题意:
给你n种树,每种树有p[i]个,每个去掉花费c[i],树高h[i]
让你去掉一些树,使得最高的树的个数占总数的一半以上
题解:
从高到底枚举树(相同高度看为一种),计算出需要去掉多少,然后二分即可
一直错的原因:top=Q.top()忘记写了、
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
struct node{
ll P,C,H;//count,cost,height
bool operator < (const node f)const{
return C<f.C;
}
}a[maxn];
ll sum[maxn],n;
ll Sum[maxn];
void add(ll pos,ll x,ll y){
while(pos<=n){
sum[pos] += x,Sum[pos] += y;
pos+=pos&-pos;
}
}
ll query(ll pos,ll ans = 0){
while(pos)ans += sum[pos],pos-=pos&-pos;
return ans;
}
ll queryValue(ll pos,ll ans = 0){
while(pos)ans += Sum[pos],pos-=pos&-pos;
return ans;
}
int main(){
while(~scanf("%lld",&n)){
for(ll i=1;i<=n;i++)scanf("%lld%lld%lld",&a[i].H,&a[i].C,&a[i].P);
sort(a+1,a+1+n);
priority_queue<pair<ll,ll> >Q;
ll last = 0,Ans = 2e18;
for(ll i=1;i<=n;i++){
add(i,a[i].P,a[i].P*a[i].C);
Q.push(make_pair(a[i].H,i));
}
while(!Q.empty()){
ll Sum = 0,Cst = 0;
pair<ll,ll> top = Q.top();
Q.pop();
ll pos = top.second;
Sum += a[pos].P;
Cst += a[pos].C*a[pos].P;
add(pos,-a[pos].P,-a[pos].P*a[pos].C);
while(!Q.empty() && top.first == Q.top().first){
top = Q.top();
pos = top.second;
add(pos,-a[pos].P,-a[pos].P*a[pos].C);
Sum += a[pos].P;
Cst += a[pos].C*a[pos].P;
Q.pop();
}
ll Need = query(n)-Sum+1,cost = last;
//printf("%lld %lld %lld\n",query(n),Sum,Need);
if(Need>0){
ll l = 1,r = n,sul = n;
while(l<=r){
ll mid = l+r>>1;
if(query(mid)>=Need)
r = mid-1,sul = mid;
else
l = mid+1;
}
//printf("sul : %d \n",sul);
ll cnt = Need-query(sul);
cost += queryValue(sul-1)+(a[sul].P+cnt)*a[sul].C;
}
Ans = min(Ans,cost);
last += Cst;
}
printf("%lld\n",Ans);
}
return 0;
}