题解:P16850 [GKS 2021 #D] Cutting Intervals
思路
多测不清空,虚空调试两小时,我已急哭。
发现题目相当于选
由于区间的端点切不了,然后离散化完中间的点可能会直接被压掉,所以离散化的时候加入一个
再记录一下离散化后的每个点相当于原来几个点就行了。
代码
#include<bits/stdc++.h>
#define int long long
#define For(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int N=3e5+10;
int t,n,c,l[N],r[N],lsh[N],d[N],sum[N],a[N];
struct sut{
int cnt,w;
}s[N];
bool cmp(sut x,sut y){
return x.cnt>y.cnt;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
For(ca,1,t){
cin>>n>>c;
int cnt=0;
memset(d,0,sizeof(d));
For(i,1,n){
cin>>l[i]>>r[i];
lsh[++cnt]=l[i],lsh[++cnt]=r[i],lsh[++cnt]=l[i]+1;
}
sort(lsh+1,lsh+cnt+1);
int len=unique(lsh+1,lsh+cnt+1)-lsh-1;
For(i,1,n){
l[i]=lower_bound(lsh+1,lsh+len+1,l[i])-lsh;
r[i]=lower_bound(lsh+1,lsh+len+1,r[i])-lsh;
d[l[i]+1]++,d[r[i]]--;
}
For(i,1,len-1) sum[i]=sum[i-1]+d[i],s[i].cnt=sum[i];
For(i,1,len-1) a[i]=lsh[i+1]-lsh[i],s[i].w=a[i];
sort(s+1,s+len,cmp);
int ans=0;
int i=1;
while(c&&i<len){
if(s[i].w<=c) c-=s[i].w,ans+=s[i].w*s[i].cnt;
else ans+=c*s[i].cnt,c=0;
i++;
}
cout<<"Case #"<<ca<<": "<<ans+n<<'\n';
}
return 0;
}