题解[CCO2020] Exercise Deadlines
Posted SharpnessV
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解[CCO2020] Exercise Deadlines相关的知识,希望对你有一定的参考价值。
考虑依次填入每个位置。
最后一个位置只能填 \\(d_i=n\\) 的位置,第 \\(k\\) 个位置只能填 \\(d_i\\ge k\\) 的位置。
我们随着 \\(k\\) 的减小,决策集合扩大。
那么对于第 \\(n\\) 个位置,一定选择 \\(d_i=n\\) 中最大的 \\(i\\) 。依次类推,第 \\(k\\) 个位置肯定选择决策集合中最大的数。
需要在线维护加入一个数,查询最大值和删除最大值,直接用优先队列即可。
最后再用树状数组求出逆序对。
#include<bits/stdc++.h>
#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;
int main(){
scanf("%d",&n);long long 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;
}
以上是关于题解[CCO2020] Exercise Deadlines的主要内容,如果未能解决你的问题,请参考以下文章
CCO '20 P2 - Exercise Deadlines