zoukankan      html  css  js  c++  java
  • bzoj3276磁力 两种要求下的最大值:分块or线段树+拓扑

    进阶指南上的做法是分块的。。

    但是线段树搞起来也挺快,将磁石按照距离排序,建立线段树,结点维护区间质量最小值的下标

    进行拓扑,每次在可行的范围内在线段树中找到质量最小的下标取出,取出后再将线段树对应的点设置成0

    查询时找区间不为0最小值的下标即可

    #include<cstdio>
    #include<algorithm>
    #define N 250010
    typedef long long ll;
    int n,i,x0,y0,nowp,x,y,r,c,v[N<<2],tmp,h=1,t,q[N];ll nowr;
    struct P{int m,p;ll d,r;}a[N];
    inline bool cmp(P x,P y){return x.d<y.d;}
    inline void read(int&a){
      char c;bool f=0;a=0;
      while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
      if(c!='-')a=c-'0';else f=1;
      while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
      if(f)a=-a;
    }
    inline ll sqr(ll x){return x*x;}
    inline int lower(){
      int l=1,r=n,t=0,mid;
      while(l<=r)if(a[mid=(l+r)>>1].d<=nowr)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline int merge(int x,int y){
      if(!x)return y;
      if(!y)return x;
      return a[x].m<a[y].m?x:y;
    }
    inline void up(int x){v[x]=merge(v[x<<1],v[x<<1|1]);}
    void build(int x,int a,int b){
      if(a==b){v[x]=a;return;}
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
    }
    void change(int x,int a,int b,int c){
      if(a==b){v[x]=0;return;}
      int mid=(a+b)>>1;
      c<=mid?change(x<<1,a,mid,c):change(x<<1|1,mid+1,b,c);
      up(x);
    }
    void ask(int x,int a,int b){
      if(b<=c){tmp=merge(tmp,v[x]);return;}
      int mid=(a+b)>>1;
      ask(x<<1,a,mid);
      if(c>mid)ask(x<<1|1,mid+1,b);
    }
    int main(){
      read(x0),read(y0),read(nowp),read(r),read(n),nowr=sqr(r);
      for(i=1;i<=n;i++){
        read(x),read(y),read(a[i].m),read(a[i].p),read(r);
        a[i].d=sqr(x-x0)+sqr(y-y0),a[i].r=sqr(r);
      }
      std::sort(a+1,a+n+1,cmp),build(1,1,n);
      if(c=lower())while(1){
        tmp=0,ask(1,1,n);
        if(!tmp||a[tmp].m>nowp)break;
        change(1,1,n,q[++t]=tmp);
      }
      while(h<=t){
        nowp=a[q[h]].p,nowr=a[q[h++]].r;
        if(c=lower())while(1){
          tmp=0,ask(1,1,n);
          if(!tmp||a[tmp].m>nowp)break;
          change(1,1,n,q[++t]=tmp);
        }
      }
      return printf("%d",t),0;
    }
  • 相关阅读:
    移植nand驱动补缺:make mrproper与make clean以及make distclean,find/grep. makefile
    repo使用
    git使用总结
    notepade++使用
    linux内核源代码、配置与编译
    linux内核介绍
    块设备
    PHP和javascript中url编码解码详解
    python中的类方法、静态方法、对象方法
    webpack+vue中安装使用vue-layer弹窗插件
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10592380.html
Copyright © 2011-2022 走看看