Codeforces - 1315D( multiset )
題目鏈接:https://codeforces.com/contest/1315/problem/D
前置知識:迭代器分爲正的和反的兩種,s.begin() = s.rend() , s.end() = s.rbegin() ///位置大約是這樣,但指針的位置好像有偏差,具體的自己本地出一個數組用multiset跑一下就好了。
需要找multiset的最後一個( 最大的那個 ) 用 mx = *s.rbegin()
需要刪除multiset的最後一個( 最大的那個 ) 用s.erase( s.find(mx) )
題意:有n個怪獸,每個怪獸有一個等級x,和其升一級需要的金幣date ,目標是讓所有的怪獸擁有各不相同的等級,問最少畫多少錢。
思路:維護一個multiset,主要用它的自動排序功能。對於等級爲x的所有怪獸必然只有1個可以留在當前等級,其餘的都需要升級到x+1等級。
先預處理給的數據,按照等級x從小到大,金幣date從小到大的順序排序。
定義now爲當前multiset維護的等級,ans爲答案,sum爲當前multiset裏所有怪獸生一級所需的金幣總數,mx爲當前等級保留的那個怪獸的升級金幣。
代碼:
#include <bits/stdc++.h>
#define int long long
using namespace std;
multiset<int> s;
struct node {
int x,date;
}a[300005];
int n;
int rule( node a, node b )
{
if ( a.x==b.x ) return a.date<b.date;
return a.x<b.x;
}
signed main()
{
cin >> n;
for ( int i=0; i<n; i++ ) scanf("%lld",&a[i].x);
for ( int i=0; i<n; i++ ) scanf("%lld",&a[i].date);
sort(a,a+n,rule);
int now = -1;
int ans=0,sum=0;
for ( int i=0; i<n; i++ ) {
while ( s.size() && now<a[i].x ) {
int mx = *s.rbegin();
s.erase(s.find(mx));
ans += sum-mx;
sum -= mx;
now ++;
}
s.insert(a[i].date);
sum += a[i].date;
now = a[i].x;
}
while ( s.size() ) {
int mx = *s.rbegin();
s.erase(s.find(mx));
ans += sum-mx;
sum -= mx;
now ++;
}
cout << ans << endl;
return 0;
}