CF1044A

注意到横着的障碍如果左端点不是 \(1\) 那么是一定不用拆的(要么把挡在它下面的左端点是 \(1\) 的障碍直接拆掉,要么拆掉若干个竖的障碍然后把左端点是 \(1\) 的障碍绕掉,反正拆了也没用,左端点是 \(1\) 的还会挡着)。那么对竖的障碍和有效的横的障碍分别按横坐标排序后,考虑二分答案,判定时如果当前已经能够拆完水平障碍就可以(除去能绕开的),否则花费 \(1\) 次拆掉最靠左的竖的障碍,继续下去即可。

注意 \(l=1,r=10^9\) 的情况,此时直接拆掉即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 500010
#define int long long
using namespace std;
int n,m,a[N],b[N],tot,mid,ans,sum;
bool ck(int x){
    for(int i=1,j=1;i<=n;i++){
        while(j<=m&&b[j]<a[i])j++;
        if(m-j+1<=x)return true;
        x--;
    }
    if(x>=0)return true;
    return false;
}
signed main(){
    int l,r,h,mid;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1);
    for(int i=1;i<=m;i++){
        cin>>l>>r>>h;
        if(l==1&&r!=1e9)b[++tot]=r;
        else if(l==1&&r==1e9)sum++;
    }
    m=tot;
    sort(b+1,b+m+1);
    l=0,r=n+m;
    while(l<=r){
        mid=(l+r)/2;
        if(ck(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<ans+sum;
    return 0;
}
posted @ 2025-09-12 08:14  FormulaOne  阅读(10)  评论(0)    收藏  举报