题解:P6642 [CCO 2020] Exercise Deadlines
解析:
考虑依次填入每个位置。
最后一个位置只能填
我们随着
那么对于第
需要在线维护加入一个数,查询最大值和删除最大值,直接用优先队列即可。
最后再用树状数组求出逆序对。
代码:
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define N 200005
using namespace std;
int n, d[N], c[N];
vector<int>u[N];
inline void add(int x) {
for (; x <= n; x += x & -x)c[x]++;
}
inline int ask(int x) {
int sum = 0;
for (; x; x -= x & -x)sum += c[x];
return sum;
}
priority_queue<int>q;
signed main() {
scanf("%d", &n);
int ans = 0;
rep(i, 1, n)scanf("%d", &d[i]), u[d[i]].push_back(i);
pre(i, n, 1) {
for (int j = 0; j < (int)u[i].size(); j++)q.push(u[i][j]);
if (q.empty()) {
puts("-1");
return 0;
}
int cur = q.top();
q.pop();
ans += ask(cur);
add(cur);
}
printf("%lld\n", ans);
return 0;
}
完结撒花,谢谢