Codeforces1555 E. Boring Segments(尺取+线段树)

题意:

在这里插入图片描述

解法:
将线段按照w从小到大排序.

然后从左到右枚举线段r,
尺取维护一个最大的l,满足[l,r]能够覆盖[1,m],
判断[l,r]中的线段能否覆盖[1,m],可以用线段树区间加法,
维护每个点被覆盖的次数,同时维护区间最小值,
如果最小值>0,说明全覆盖了.

对于满足条件的区间,用w的差值更新答案即可.

算法总复杂度O(n*log)

ps:
这题其实说的不是区间覆盖,而是能够连通,
例如[1,3][4,5]是不连通的,因为线段之间没有相交
而[1,3][3,5]是连通的.
处理方法是将m--,每条线段的右端点r--,
这样的话就不需要判相交,只需要判断是否覆盖了[1,m]就行了.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
struct Node{
    int l,r,w;
}e[maxm];
bool cmp(Node a,Node b){
    return a.w<b.w;
}
struct Tree{
    int mi[maxm<<2];
    int laz[maxm<<2];
    void pp(int node){
        mi[node]=min(mi[node*2],mi[node*2+1]);
    }
    void pd(int node){
        if(laz[node]){
            mi[node*2]+=laz[node];
            mi[node*2+1]+=laz[node];
            laz[node*2]+=laz[node];
            laz[node*2+1]+=laz[node];
            laz[node]=0;
        }
    }
    void update(int st,int ed,int val,int l,int r,int node){
        if(st<=l&&ed>=r){
            laz[node]+=val;
            mi[node]+=val;
            return ;
        }
        pd(node);
        int mid=(l+r)/2;
        if(st<=mid)update(st,ed,val,l,mid,node*2);
        if(ed>mid)update(st,ed,val,mid+1,r,node*2+1);
        pp(node);
    }
}T;
int n,m;
void solve(){
    cin>>n>>m;
    m--;
    for(int i=1;i<=n;i++){
        int l,r,w;cin>>l>>r>>w;
        r--;
        e[i]={l,r,w};
    }
    sort(e+1,e+1+n,cmp);
    int ans=1e18;
    int l=1;
    for(int i=1;i<=n;i++){
        T.update(e[i].l,e[i].r,1,1,m,1);
        while(T.mi[1]>0){
            ans=min(ans,e[i].w-e[l].w);
            T.update(e[l].l,e[l].r,-1,1,m,1);
            l++;
        }
    }
    cout<<ans<<endl;
}
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);
    solve();
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值