洛谷P2073 送花
标签
- vector乱搞
简明题意
-
维护一个序列(拥有价格和权值两种属性),支持一下操作
- 添加一个元素
- 删除价格最大的元素
- 删除价格最小的元素
-
最后需要你同意所有元素的权值和
思路
- 很显然这是一个vector乱搞了,我们只需要始终维护一个单调增的序列即可
- 对于操作1,先二分找到应在的位置,然后insert进去就可以了。复杂度 O ( l g n ) O(lg n) O(lgn)
- 对于操作23,直接insert到begin或end,复杂度一个是O(1),一个是O(n)
注意事项
- 一定要注意这句话如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。,也就是得用lower_bound二分到后,判断一下,这个值是不是和要加入的值相等,相等就不加。
- 但是又有个更坑的地方,就是可能二分到的位置是end,这个时候你判,这个值是不是和要加入的值相等,就挂了,因为end是空…
总结
- 总之要注意迭代器end()是不能取他的成员的
AC代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct Node
{
int w, c;
Node(int w, int c) : w(w), c(c) {}
bool operator < (const Node& a)const
{
return c < a.c;
}
};
vector<Node> a;
void solve()
{
int opt;
while (~scanf("%d", &opt))
{
if (opt == 1)
{
int w, c;
scanf("%d%d", &w, &c);
vector<Node>::iterator it = lower_bound(a.begin(), a.end(), Node(0, c));
if (it != a.end() && it->c == c)
continue;
a.insert(it, Node(w, c));
//(*upper_bound(a.begin(), a.end(), Node(0, c))) = Node(w, c);
}
else if (opt == 2)
{
if (!a.empty())
a.erase(a.end() - 1);
}
else if (opt == 3)
{
if (!a.empty())
a.erase(a.begin());
}
else
break;
}
long long beaut = 0, mony = 0;
for (int i = 0; i < a.size(); i++)
beaut += a[i].w, mony += a[i].c;
printf("%lld %lld\n", beaut, mony);
}
int main()
{
freopen("Testin.txt", "r", stdin);
solve();
return 0;
}
双倍经验
- 无