zoukankan      html  css  js  c++  java
  • [BZOJ 4082] Surveillance

    Link:

    BZOJ 4082 传送门

    Solution:

    对于链上这样的问题贪心就好了

    如果在一个环上,肯定需要将环转化成链,$O(n)$确定起点才能计算

    但枚举每个节点拆环再贪心的复杂度为$O(n^2)$,明显会超时

    于是我们要将已知起点,计算从起点走完一圈的距离的时间复杂度降到$log(n)$

    这时联想到倍增算法:

    将所有区间按照右端点排序后,将每个区间和其能达到的右端点最远的区间相连

    可以发现,这样就形成了一个$DAG$(每个点都只会向后连边)

    接下来只要对于每个点在$DAG$上倍增即可,计算当右端点回到该点起点时的距离

    Tip:$BZOJ$的题面上没写如无解则输出$impossible$

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef pair<int,int> P;
    #define X first
    #define Y second
    const int MAXN=1e6+10,INF=1<<27;
    P dat[MAXN];
    int l,n,f[MAXN][25],mn[MAXN],res;
    
    bool cmp(P a,P b){return a.Y<b.Y;}
    
    int main()
    {
        scanf("%d%d",&l,&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&dat[i].X,&dat[i].Y);
            if(dat[i].Y<dat[i].X) dat[i].Y+=l;
        }
        sort(dat+1,dat+n+1,cmp);
        
        mn[n+1]=INF;res=INF;
        for(int i=n;i>=1;i--) mn[i]=min(mn[i+1],dat[i].X);
        int cur=1;
        for(int i=1;i<=n;i++)
        {
            while(cur<n && mn[cur+1]-1<=dat[i].Y) cur++;
            if(cur!=i) f[i][0]=cur;
        }
        for(int i=n;i>=1;i--)
            for(int j=1;j<=20;j++)
                f[i][j]=f[f[i][j-1]][j-1];
        
        for(int i=1;i<=n;i++)
        {
            int cur=i,cnt=1;
            for(int j=20;j>=0;j--)
                if(f[cur][j] && dat[f[cur][j]].Y<dat[i].X+l-1) cur=f[cur][j],cnt+=1<<j;
            if(f[cur][0] && dat[cur].Y<dat[i].X+l-1) cur=f[cur][0],cnt++;
            if(dat[cur].Y>=dat[i].X+l-1) res=min(res,cnt);
        }
        if(res==INF) puts("impossible");
        else printf("%d
    ",res);
        return 0;
    }
  • 相关阅读:
    在路上——7月英语
    Today is a special day for English Topic
    三级网络-不单单是学知识
    停下是为了更好的出发
    量变引发质变--【2015年计算机年终总结】
    这个月,小美很忙
    一个人牛逼不如一群人一起牛逼——致我最亲爱的程序员
    掀起你的盖头来--【2015年英语年终总结】
    平凡之路之小美
    小美的猴年年中总结,挪不开眼~
  • 原文地址:https://www.cnblogs.com/newera/p/9241728.html
Copyright © 2011-2022 走看看