Minimal Segment Cover

前言

最近需要把效率提起来, 注意写题不能太水, 要多自己想

思路

转化题意
给定 n 个线段,每个线段形如 [l,r]
m 次询问,每次询问给出 x,y , 求至少选多少个线段才能使这些线段的并能包含线段 [x,y]

又是这一类线段题, 我们也是做过不少

不用想的太复杂, 我们先考虑一个贪心做法, 对于每一个点, 我们尽可能的往右边选择, 然后再跳到右边的位置之后继续贪心, 这样是 O(nq)

考虑优化, 容易发现我们可以优化跳的次数, 类似于倍增

代码

#include <bits/stdc++.h>

const int MAXN = 5e5 + 10;
int n, q, f[MAXN][25], k;

int main()
{
    scanf("%d %d", &n, &q);
    for (int i = 1; i <= n; i++)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        f[l][0] = std::max(f[l][0], r);
        k = max(k, r);
    }
    for (int i = 1; i <= k; i++)
        f[i][0] = std::max(f[i][0], f[i - 1][0]);
    for (int i = 1; i <= 20; i++)
        for (int j = 0; j <= k; j++)
            f[j][i] = f[f[j][i - 1]][i - 1];
    while (q--)
    {
        int l, r, ans = 0;
        scanf("%d %d", &l, &r);
        for (int i = 20; i >= 0; i--)
            if (f[l][i] < r)
            {
                ans += 1 << i;
                l = f[l][i];
            }
        printf("%d\n", f[l][0] >= r ? ans + 1 : -1);
    }
    return 0;
}

总结

倍增优化一类跳跃问题

posted @   Yorg  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示