首页 > 其他 > 详细

【题解】[CCO2020] Exercise Deadlines

时间:2021-06-07 20:17:06      阅读:25      评论:0      收藏:0      [点我收藏+]

考虑依次填入每个位置。

最后一个位置只能填 \(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

原文:https://www.cnblogs.com/SharpnessV/p/14859590.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!