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

    链上是经典贪心问题,将线段全按左端点排序后把点全撒在线段右端点上。这里放到环上,倍长即可。

    题目保证不存在区间包含情况,于是有一种暴力做法,先将战士的管辖区间按左端点从小到大排序,对于询问x,从x战士出发,每次走到最远(管辖区间左端点最大)的一个战士,满足这个战士的区间左端点被x的区间右端点覆盖到,然后让这个战士接替x继续传递。$O(n^2)$

    这显然可以倍增优化,f[i][j]表示从战士i开始共$2^j$个战士参与传递,最远可以传递到哪个战士的手中。$O(nlog n)$

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 using namespace std;
     5 
     6 const int N=400010;
     7 int n,m,ans[N],f[N][20];
     8 
     9 struct P{ int l,r,id; }a[N];
    10 bool operator <(const P &a,const P &b){ return a.l<b.l; }
    11 
    12 int main(){
    13     freopen("bzoj4444.in","r",stdin);
    14     freopen("bzoj4444.out","w",stdout);
    15     scanf("%d%d",&n,&m);
    16     rep(i,1,n){
    17         scanf("%d%d",&a[i].l,&a[i].r); a[i].id=i;
    18         if (a[i].l>a[i].r) a[i].r+=m;
    19     }
    20     sort(a+1,a+n+1);
    21     rep(i,n+1,n*2) a[i]=(P){a[i-n].l+m,min(m*2,a[i-n].r+m),a[n-i].id};
    22     int R=1;
    23     rep(i,1,n*2){
    24         while (R<n*2 && a[R+1].l<=a[i].r) R++;
    25         f[i][0]=R;
    26     }
    27     rep(j,1,19) rep(i,1,n*2) f[i][j]=f[f[i][j-1]][j-1];
    28     rep(i,1,n){
    29         int x=i,cnt=1;
    30         for (int j=19; ~j; j--) if (f[x][j]-i<n) cnt+=1<<j,x=f[x][j];
    31         ans[a[i].id]=cnt;
    32     }
    33     rep(i,1,n) printf("%d ",ans[i]);
    34     return 0;
    35 }
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10054371.html
Copyright © 2011-2022 走看看