• [SCOI2015]国旗计划


    [SCOI2015]国旗计划

    BZOJ
    luogu
    先考虑破环为链
    由于区间不包含,我们sort之后可以贪心的选左端点在当前右端点之前的最后一个
    然后预处理一个倍增数组,每次logn查一下
    复杂度(O(nlogn))
    空间两倍,tot+1的r设为inf

    #include<bits/stdc++.h>
    using namespace std;
    const int _=4e5+5;
    int re(){
        int x=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    int n,m,tot,ans[_],f[20][_];
    struct node{int l,r,id;}s[_];
    bool cmp(node a,node b){return a.r<b.r;}
    int solve(int x,int R){
        int res=0;
        for(int i=18;i>=0;i--)
            if(s[f[i][x]].r<R){
                res+=(1<<i);
                x=f[i][x];
            }
        return res+2;
    }
    int main(){
        tot=n=re(),m=re();
        for(int i=1;i<=n;i++){
            int l=re(),r=re();
            if(l>r)s[i]=(node){l,r+m,i};
            else s[i]=(node){l,r,i},s[++tot]=(node){l+m,r+m};
        }
        sort(s+1,s+tot+1,cmp);s[0].r=s[tot+1].r=2e9+1;
        for(int i=1,j=1;i<=tot;i++){
            while(s[j+1].l<=s[i].r&&j<=tot)j++;
            f[0][i]=j;
        }
        for(int i=1;i<=18;i++)
            for(int j=1;j<=tot;j++)
                f[i][j]=f[i-1][f[i-1][j]];
        for(int i=1;i<=n;i++)
            ans[s[i].id]=solve(i,s[i].l+m);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    杭电1058
    动态规划之背包模版
    按字典序依次打印只由1~n组成的n位数
    杭电1029
    杭电1257
    杭电2191
    杭电1114
    杭电2602
    南阳975
    杭电2138
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/9891128.html
Copyright © 2020-2023  润新知