国旗计划

题目:A 国正在开展一项伟大的计划 —— 国旗计划。这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈。这项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了 N N 名优秀的边防战上作为这项计划的候选人。

A 国幅员辽阔,边境线上设有 M M 个边防站,顺时针编号 1 1 至 M M。每名边防战士常驻两个边防站,并且善于在这两个边防站之间长途奔袭,我们称这两个边防站之间的路程是这个边防战士的奔袭区间。 N N 名边防战士都是精心挑选的,身体素质极佳,所以每名边防战士的奔袭区间都不会被其他边防战士的奔袭区间所包含。

现在,国十安全局局长希望知道,至少需要多少名边防战士,才能使得他们的奔袭区间覆盖全部的边境线,从而顺利地完成国旗计划。不仅如此,安全局局长还希望知道更详细的信息:对于每一名边防战士,在他必须参加国旗计划的前提下,至少需要多少名边防战士才能覆盖全部边境线,从而顺利地完成国旗计划。
输入:
第一行,包含两个正整数 N, M N,M,分别表示边防战士数量和边防站数量。

随后 n 行,每行包含两个正整数。其中第 i i 行包含的两个正整数 C_i C
i

、 D_i D
i

分别表示 i i 号边防战士常驻的两个边防站编号,

号边防站沿顺时针方向至 D_i D
i

号边防站力他的奔袭区间。数据保证整个边境线都是可被覆盖的。

#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 400005
struct p{int l,r,num;}a[MAX];
int jump[MAX][17],ans[MAX],tmp,n,m,top,l,r,now,to;
bool cmp(p a,p b){
    return a.l<b.l;
}
int main(){
    cin>>n>>m;
    a[0]=p{0x7fffffff,0x7fffffff,0x7fffffff};
    for(int i=1;i<=n;i++){
        cin>>l>>r;
        if(r<l)r+=m;
        a[++top]=p{l,r,i};
        a[++top]=p{l+m,r+m,0};
    }
    sort(a+1,a+2*n+1,cmp);
    for(int i=1,xibo=1;i<=2*n;i++){
        while(a[xibo].l<=a[i].r&&xibo<=2*n)xibo++;
        jump[i][0]=xibo-1;
    }
    for(int j=1;j<=16;j++)for(int i=1;i<=2*n;i++)jump[i][j]=jump[jump[i][j-1]][j-1];
    for(int i=1;i<=2*n;i++){
        if(a[i].num){
            tmp=0,now=i;
            for(int j=16;j>=0;j--)if(jump[now][j]&&a[jump[now][j]].r<a[i].l+m)now=jump[now][j],tmp+=(1<<j);
            ans[a[i].num]=tmp+2;
        }
    }
    for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
}

转载于:https://www.cnblogs.com/SZJZC/p/11543751.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值