題面
題意
在魚缸中有一些魚,這些魚之間會相互吞噬直到只剩下一條魚,若一條魚的質量爲a,另一條魚的質量爲b,則吞噬之後會剩下一條質量爲a+b的魚,若且,則這次吞噬是危險的。
現在有一個空魚缸,進行多次操作,每次操作會加入一條魚或去掉某一條魚,問這次操作後,魚缸中的魚相互吞噬直到只剩下一條魚,至多有幾次是危險的。
做法
首先考慮怎樣吞噬纔會使危險次數最多,可以發現如果每次挑選最輕的兩條魚互吞,答案最大,進一步可以發現,對所有魚按質量進行排序後,若一條魚與其他魚合併會對答案造成貢獻,當且僅當
現在考慮維護這個東西。
根據魚的質量將其分爲30個區間:
然後可以發現,如果一個區間中有多個元素,則只有最小的元素可能不是危險的,因此我們只要維護每個區間的和,每次詢問暴力計算即可
代碼
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll Q,ans,sum[40];
char str[2];
multiset<ll>num[40];
int main()
{
ll i,j,t,qz;
cin>>Q;
while(Q--)
{
scanf("%s%lld",str,&t);
for(i=1;(1 << i)<=t;i++);i--;
if(str[0]=='+')
{
sum[i]+=t;
num[i].insert(t);
}
else
{
sum[i]-=t;
num[i].erase(num[i].find(t));
}
qz=ans=0;
for(i=0;i<30;i++)
{
if(!num[i].size()) continue;
ans+=(num[i].size()-((*num[i].begin())>2*qz));
qz+=sum[i];
}
printf("%lld\n",ans);
}
}