zoukankan      html  css  js  c++  java
  • [USACO18FEB] Snow Boots G (离线+并查集)

    题目大意:略

    网上各种神仙做法,本蒟蒻只想了一个离线+并查集的做法

    对所有靴子按最大能踩的深度从大到小排序,再把所有地砖按照积雪深度从大到小排序

    一个小贪心思想,我们肯定是在 连续不能踩的地砖之前 的一个位置开始跳,如果这都不能跳过这一段连续的坏地砖,说明这个靴子肯定不能用

    那么离线靴子以后,会发现不能踩的瓷砖是逐渐添加上去的,相当于求序列中最长连续坏点的长度

    可以用并查集维护,一个点如果不能踩,就去merge它左右也不能踩的地砖,即积雪深度大于等于这块地砖

    再用并查集维护一个size表示当前联通块大小,发现最大的size始终都是递增的,所以并不需要什么额外的数据结构去维护

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define N 100100
     5 using namespace std;
     6 
     7 int n,B;
     8 int f[N],fa[N],sz[N];
     9 struct node{int id,dep;}d[N];
    10 struct Boot{int s,d,ans,id;}b[N];
    11 int cmpnode1(node s1,node s2){return s1.dep>s2.dep;}
    12 int cmp1(Boot s1,Boot s2){return s1.s>s2.s;}
    13 int cmp2(Boot s1,Boot s2){return s1.id<s2.id;}
    14 int find_fa(int x){
    15     int y=x;
    16     while(fa[y]!=y) y=fa[y];
    17     while(fa[x]!=y){
    18         int pre=fa[x];
    19         fa[x]=y;
    20         x=pre;
    21     }return y;
    22 }
    23 
    24 int main()
    25 {
    26     scanf("%d%d",&n,&B);
    27     for(int i=1;i<=n;i++)
    28         scanf("%d",&f[i]),d[i].dep=f[i],d[i].id=i,fa[i]=i,sz[i]=1;
    29     for(int i=1;i<=B;i++)
    30         scanf("%d%d",&b[i].s,&b[i].d),b[i].id=i;
    31     sort(b+1,b+B+1,cmp1);
    32     sort(d+1,d+n+1,cmpnode1);
    33     int k=1,x,y,fx,fy,ma=0;
    34     for(int i=1;i<=n;i++)
    35     {
    36         while(d[k].dep>b[i].s)
    37         {
    38             x=d[k].id,fx=find_fa(x),ma=max(ma,sz[fx]);
    39             if(f[x-1]>=f[x]){
    40                 y=x-1,fy=find_fa(y);
    41                 if(fy!=fx) fa[fy]=fx,sz[fx]+=sz[fy],ma=max(ma,sz[fx]);
    42             }
    43             if(f[x+1]>=f[x]){
    44                 y=x+1,fy=find_fa(y);
    45                 if(fy!=fx) fa[fy]=fx,sz[fx]+=sz[fy],ma=max(ma,sz[fx]);
    46             }k++;
    47         }
    48         if(ma>b[i].d-1) b[i].ans=0;
    49         else b[i].ans=1;
    50     }
    51     sort(b+1,b+B+1,cmp2);
    52     for(int i=1;i<=B;i++)
    53         printf("%d
    ",b[i].ans);
    54     return 0;
    55 }
  • 相关阅读:
    bzoj 5028小Z的加油店(D12 序列gcd)(线段树+树状数组)
    蒲公英
    [APIO2012]派遣(可并堆)(D11)
    AT1219 歴史の研究(回滚莫队)
    [USACO05DEC] 布局
    小B的询问
    [HEOI2012]采花(树状数组)(暑假D11)
    [JLOI2011]飞行路线 (暑假D3 拆点+dijkstra堆优化)
    [POI2012]FES-Festival
    [国家集训队]拉拉队排练
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9797427.html
Copyright © 2011-2022 走看看