【题解】 UVA1707 【Surveillance】

本文介绍了一种解决环状路径上寻找最短覆盖路径的问题。通过将环形结构转化为链式结构,并采用倍增预处理的方法来高效计算从任意点出发覆盖特定长度所需的最少线段数目。利用差分思想及集合操作辅助计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到是环,于是我们非常套路地把它拉成链。

接着就要枚举一个起点iii,找到至少覆盖到i+len−1i+len-1i+len1这个位置需要使用的最少线段数。

由于每个点都要计算,所以可以考虑预处理倍增,计算pi,jp_{i,j}pi,j表示从iii开始,使用2j2^j2j条线段不能覆盖的第一个位置。转移即为pi,j=ppi,j−1,j−1p_{i,j}=p_{p_{i,j-1},j-1}pi,j=ppi,j1,j1

pi,0p_{i,0}pi,0即为覆盖iii点的线段的最大右端点,可以用差分的思想,配合一个set维护。

接着枚举每一个点,在不超过i+len−1i+len-1i+len1的范围内尽量跳(类似求LCA的过程),最后判断一下能否完全覆盖即可。

代码

#include <bits/stdc++.h>
#define MAX 2000005
#define INF 0x3f3f3f3f
using namespace std;

struct node{
    int l, r;
}a[MAX];
int m, n;
int p[MAX][24];
vector<int> v[MAX];
multiset<int> s;

int main()
{
    while(cin >> m >> n){
        memset(p, 0, sizeof(p));
        for(int i = 1; i <= m*2; i++) v[i].clear();
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &a[i].l, &a[i].r);
            if(a[i].r < a[i].l) a[i].r += m;
            v[a[i].l].push_back(a[i].r);
            v[a[i].r+1].push_back(-a[i].r);
        }
        s.clear();
        for(int i = 1; i <= m*2; i++){
            for(int x:v[i]){
                if(x > 0) s.insert(x);
                else s.erase(s.find(-x));
            }
            if(!s.empty()) p[i][0] = *s.rbegin()+1;
            else p[i][0] = i;
        }
        for(int j = 1; j <= 21; j++){
            for(int i = 1; i <= m*2; i++){
                p[i][j] = p[p[i][j-1]][j-1];
            }
        }
        int ans = INF;
        for(int i = 1; i <= m; i++){
            int x = i, t = 0;
            for(int j = 21; j >= 0; j--){
                if(p[x][j] <= i+m-1) x = p[x][j], t += (1<<j);
            }
            if(p[x][0] > i+m-1) ans = min(ans, t+1);
        }
        if(ans == INF) puts("impossible");
        else cout<<ans<<endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值