zoukankan      html  css  js  c++  java
  • [P4155][SCOI2015] 国旗计划 (贪心+倍增)

    题意:给一个环和多个区间,且不存在被包含区间,求在已选定第 i个区间时( i 属于 ( 1,n ) ),总共需要多少段区间才可将整个环给覆盖完;

    解法:贪心+倍增;

    1.贪心;区间覆盖问题的较常见的一个解决思路就是按端点排序,如果是环的话,还要断环为链;

    1.贪心;题目中说到不存在被包含区间,即不存在任意两个区间,使得其中的一个区间被另一个区间包含,那么我们可以知道不会有任意两条线段的同一边的端点重合,所以我们就可以在排完序后进行倍增预处理;设 f[i][j]为第 i条线段跳了 2^j步后可以到达的线段序号,在处理的时候,要注意一下边界;

    附上代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<map>
    #define ll long long
    #define rg register
    using namespace std;
    const int N = 4e5+10;
    
    inline int read(){
        int ref=0,x=1;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) ref=ref*10+ch-'0',ch=getchar();
        return ref*x;
    }
    
    int n,m;
    struct node{
        int l,r,id;
    }a[N];
    int f[N][20],rel[N>>1];
    
    bool cmp(node a,node b){
        return a.l<b.l;
    }
    
    void prepare(){
        int limit=2*n;
        for(int i=1,pos=i;i<=limit;++i){
            while(pos<=limit&&a[pos].l<=a[i].r) pos++;
            f[i][0]=pos-1;
        }
        for(rg int j=1;j<20;++j)
        for(rg int i=1;i<=limit;++i) f[i][j]=f[f[i][j-1]][j-1];
    }
    
    void deal(int x){
        int end=a[x].l+m,ans=1,fina=x;
        for(rg int i=19;i>=0;i--){
            int pre=f[x][i];
            if(a[pre].r<end) ans+=(1<<i),x=pre;
        }
        rel[a[fina].id]=ans+1;
    }
    
    int main()
    {
        n=read(),m=read();
        for(rg int i=1;i<=n;++i){
            a[i].l=read(),a[i].r=read();
            if(a[i].l>a[i].r) a[i].r+=m;
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        for(rg int i=1;i<=n;++i){
            a[i+n]=a[i];
            a[i+n].l=a[i].l+m;
            a[i+n].r=a[i].r+m;
        }
        prepare();
        for(rg int i=1;i<=n;++i) deal(i);
        for(rg int i=1;i<=n;++i) printf("%d ",rel[i]);
        return 0;
    }
  • 相关阅读:
    js将时间戳转化为时间,(不省略0)
    SpringMVC路径传参
    贪心算法及实例
    剪绳子(贪心算法)
    c语言输入一行未知个数数字存入数组
    Netlink机制详解
    new和malloc的区别
    堆 和 栈的 区别
    strlen与sizeof区别(转载)
    任务
  • 原文地址:https://www.cnblogs.com/nnezgy/p/11545145.html
Copyright © 2011-2022 走看看