zoukankan      html  css  js  c++  java
  • bzoj4082

    贪心+倍增

    首先如果这个问题在序列上,好像可以按右端点排序,然后从起点开始向能到的最远的地方走。

    但是环上不可以,因为随即一个起点可能不是最小的。

    然后神思路来了:我们先将环展开倍增,再将区间按右端点排序,然后每个区间连向能达到最远的区间连边。因为每个区间只向外连一条边,而且最后一个区间没有后继,所以这是一颗树。(森林不可能吧,因为每个点都被覆盖了,那么每个区间都有后继,到达最后的区间时肯定有会归到最后一个区间)枚举每个区间,向上倍增,因为每个区间的祖先右端点都要大一些,所以只要倍增到自己左端点时就是答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1000010;
    struct cover {
        int x, y;
    } a[N];
    int n, len, ans = 1 << 29;
    int fa[N][23], dep[N], mn[N];
    bool cp(cover x, cover y)
    {
        return x.y < y.y;
    }
    int query(int x, int limit)
    {
        for(int i = 22; i >= 0; --i) 
            if(fa[x][i] != -1 && a[fa[x][i]].y < limit)
                x = fa[x][i];
        return a[x].y >= limit ? x : fa[x][0];
    }
    void getdep(int x)
    {
        if(dep[x]) 
            return;
        if(fa[x][0] == -1)
        {
            dep[x] = 1;
            return;
        }
        getdep(fa[x][0]);
        dep[x] = dep[fa[x][0]] + 1;
    }
    int main()
    {
        scanf("%d%d", &len, &n);
        for(int i = 1; i <= n; ++i)
        {
            scanf("%d%d", &a[i].x, &a[i].y);
            if(a[i].y < a[i].x) 
                a[i].y += len;
        }
        sort(a + 1, a + n + 1, cp);
        int j = 1;
        memset(fa, -1, sizeof(fa));
        memset(mn, 0x3f3f, sizeof(mn));
        for(int i = n; i; --i)
            mn[i] = min(mn[i + 1], a[i].x);
        for(int i = 1; i <= n; ++i)
        {
            while(a[i].y >= mn[j + 1] - 1 && j < n) 
                ++j;
            fa[i][0] = j == i ? -1 : j;
        }
        for(int i = 1; i <= n; ++i)
            getdep(i);
        for(int k = 1; k <= 22; ++k)
            for(int i = 1; i <= n; ++i)
                if(fa[i][k - 1] != -1)
                    fa[i][k] = fa[fa[i][k - 1]][k - 1];
        for(int i = 1; i <= n; ++i)
        {
            int x = query(i, a[i].x + len - 1);
            if(x != -1) 
                ans = min(ans, dep[i] - dep[x] + 1);
        }
        if(ans != 1 << 29)
            printf("%d
    ", ans);
        else
            puts("impossible");
        return 0;
    }
    View Code
  • 相关阅读:
    django模型的crud操作
    django模型中的关系对应
    django中模型详解-字段类型与约束条件
    django中的模型详解-1
    运维自动化轻量级工具pssh
    zabbix告警使用sendEmail
    nginx正向代理,反向代理,透明代理(总结)
    nginx.conf的events,http段一般固定配置
    nginx实战2---浏览器设置缓存
    nginx之location
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7066027.html
Copyright © 2011-2022 走看看