zoukankan      html  css  js  c++  java
  • BZOJ4662 : Snow

    首先离散化,即相邻关键点之间的部分可以压成一段。

    注意到区间互不包含,因此排序后每个位置的清理影响到的是一段连续区间的清理工的工作长度。

    这显然可以用线段树维护,支持区间减去一个数,单点加上$inf$,以及查询全局最小值。

    对于每次清理,暴力枚举区间内所有没清理过的段,在线段树中区间修改,用并查集进行路径压缩即可。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef pair<int,int>P;
    const int N=300010,M=1050000,inf=1000000010;
    int n,m,i,j,x,b[N<<1],f[N<<1],tag[M];P v[M];struct E{int l,r;}a[N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void add(int x,int p){v[x].first+=p;tag[x]+=p;}
    inline void pb(int x){if(tag[x])add(x<<1,tag[x]),add(x<<1|1,tag[x]),tag[x]=0;}
    void build(int x,int a,int b){
      if(a==b){v[x]=P(::a[a].r-::a[a].l,a);return;}
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
      v[x]=min(v[x<<1],v[x<<1|1]);
    }
    void del(int x,int a,int b,int c){
      if(a==b){v[x].first+=inf;return;}
      pb(x);
      int mid=(a+b)>>1;
      if(c<=mid)del(x<<1,a,mid,c);else del(x<<1|1,mid+1,b,c);
      v[x]=min(v[x<<1],v[x<<1|1]);
    }
    void change(int x,int a,int b,int c,int d,int p){
      if(c<=a&&b<=d){add(x,p);return;}
      pb(x);
      int mid=(a+b)>>1;
      if(c<=mid)change(x<<1,a,mid,c,d,p);
      if(d>mid)change(x<<1|1,mid+1,b,c,d,p);
      v[x]=min(v[x<<1],v[x<<1|1]);
    }
    int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
    inline int lower(int x){
      int l=1,r=m,mid,t;
      while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline int getl(int c,int d){
      int l=1,r=n,mid,t;
      while(l<=r){
        mid=(l+r)>>1;
        if(a[mid].r<=c)l=mid+1;
        else if(a[mid].l>=d)r=mid-1;
        else r=(t=mid)-1;
      }
      return t;
    }
    inline int getr(int c,int d){
      int l=1,r=n,mid,t;
      while(l<=r){
        mid=(l+r)>>1;
        if(a[mid].r<=c)l=mid+1;
        else if(a[mid].l>=d)r=mid-1;
        else l=(t=mid)+1;
      }
      return t;
    }
    inline void clean(int l,int r){
      int x=lower(l);
      while(1){
        x=F(x);
        if(b[x]>=r)return;
        f[x]++;
        change(1,1,n,getl(b[x],b[x+1]),getr(b[x],b[x+1]),b[x]-b[x+1]);
      }
    }
    int main(){
      read(n);read(n);
      for(i=1;i<=n;i++){
        read(a[i].l),read(a[i].r);
        b[++m]=a[i].l,b[++m]=a[i].r;
      }
      sort(b+1,b+m+1);
      for(i=1;i<=m;i++)if(b[i]!=b[i-1])b[++j]=b[i];
      m=j;
      for(i=1;i<=m;i++)f[i]=i;
      build(1,1,n);
      for(i=1;i<=n;i++){
        x=v[1].second;
        printf("%d
    ",x);
        del(1,1,n,x);
        clean(a[x].l,a[x].r);
      }
      return 0;
    }
    

      

  • 相关阅读:
    修改mysql root 密码
    web.xml中contextConfigLocation的作用
    项目中提示找不到class,跟命名规则有关系RulesConfigDao
    myBatis抛出异常Result Maps collection already contains value ...
    mysql 远程访问授权
    maven项目依赖小试牛刀+私库
    eclipse中复制项目更名注意事项
    在eclipse中的tomcat内存设置
    广告宣传单页制作的注意事项
    Linux系统的负载与CPU、内存、硬盘、用户数监控的shell脚本
  • 原文地址:https://www.cnblogs.com/clrs97/p/5727812.html
Copyright © 2011-2022 走看看