【codeforces】【Round#523D】TV shows

时间:2023-03-08 22:59:36
【codeforces】【Round#523D】TV shows

题意:n个节目,每个节目的播放时间为[li,ri],你需要选择一些电视机全部播放这些节目,一台电视机不能同时播放多个节目,选择一个新的电视机代价为x , 如果某台电视机的使用时间为[Li,Ri]需要付出(Ri-Li)*y的代价,问最小的代价;

题解:
        答案是选由于使用电视播放节目的代价是固定的,所以只需要让浪费的使用时间和选择一个新的电视的代价之和最小即可,左端点排序,对于[li,ri],每次选择前面使得rj<li的rj最大的(lj,rj),将x和(li-rj)*y比较讨论;

cf的题解里面写了证明,但是我总感觉不太严谨的样子。。。。。

具体实现用multiset;

 #include<cstdio>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
const int N= ,mod=1e9+;
int n,ans,x,y;
struct node{
int x,y;
bool operator <(const node&A)const{
return x == A.x ? y < A.y : x < A.x;
}
}a[N];
multiset<int>s;
multiset<int>::iterator it;
int main(){
// freopen("D.in","r",stdin);
// freopen("D.out","w",stdout);
scanf("%d%d%d",&n,&x,&y);
for(int i=;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
ans = (ans + 1ll * y * (a[i].y - a[i].x) %mod)%mod;
}
sort(a+,a+n+);
for(int i=;i<=n;i++){
it = s.lower_bound(a[i].x);
if(it==s.begin() || 1ll*(a[i].x-*(--it)) * y >= x){
ans=(ans+x)%mod;
s.insert(a[i].y);
}else{
ans=(ans+1ll*(a[i].x-*it) * y%mod)%mod;
s.erase(it);
s.insert(a[i].y);
}
}
printf("%d\n",ans);
return ;
}