zoukankan      html  css  js  c++  java
  • BZOJ3941 : [Usaco2015 Feb]Fencing the Herd

    若所有点同侧则表明将各个点带入直线解析式ax+by-c后得到的值均同号
    等价于最大值和最小值同号
    考虑CDQ分治,每一步分治的过程中求出上下凸壳,然后三分答案即可
    时间复杂度$O(nlog^2n)$

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    const int N=200010;
    const ll inf=1LL<<60;
    struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}}b[N],q1[N],q2[N],now;
    struct Q{int a,b,q;ll c;Q(){}Q(int _a,int _b,ll _c,int _q){a=_a,b=_b,c=_c,q=_q;}}a[N];
    int n,m,i,op,A,B,cnt,t1,t2,m1,m2,len;ll C,s1,s2,ans1[N],ans2[N];
    inline bool cmp1(P a,P b){return a.x==b.x?a.y>b.y:a.x<b.x;}
    inline bool cmp2(P a,P b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    inline ll mul(P b){return(ll)now.x*b.x+(ll)now.y*b.y;}
    inline void Max(ll&a,ll b){if(a<b)a=b;}
    inline void Min(ll&a,ll b){if(a>b)a=b;}
    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 void read(ll&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 void askmax1(ll&t){
      for(int l=0,r=t1;l<=r&&t<C;){
        len=(r-l)/3;
        if((s1=mul(q1[m1=l+len]))>(s2=mul(q1[m2=r-len])))Max(t,s1),r=m2-1;else Max(t,s2),l=m1+1;
      }
    }
    inline void askmax2(ll&t){
      for(int l=0,r=t2;l<=r&&t<C;){
        len=(r-l)/3;
        if((s1=mul(q2[m1=l+len]))>(s2=mul(q2[m2=r-len])))Max(t,s1),r=m2-1;else Max(t,s2),l=m1+1;
      }
    }
    inline void askmin1(ll&t){
      for(int l=0,r=t1;l<=r&&t>C;){
        len=(r-l)/3;
        if((s1=mul(q1[m1=l+len]))<(s2=mul(q1[m2=r-len])))Min(t,s1),r=m2-1;else Min(t,s2),l=m1+1;
      }
    }
    inline void askmin2(ll&t){
      for(int l=0,r=t2;l<=r&&t>C;){
        len=(r-l)/3;
        if((s1=mul(q2[m1=l+len]))<(s2=mul(q2[m2=r-len])))Min(t,s1),r=m2-1;else Min(t,s2),l=m1+1;
      }
    }
    void solve(int l,int r){
      if(l==r)return;
      int mid=(l+r)>>1;
      solve(l,mid),solve(mid+1,r);
      for(cnt=0,i=l;i<=mid;i++)if(!a[i].q)b[cnt++]=P(a[i].a,a[i].b);
      if(!cnt)return;
      for(std::sort(b,b+cnt,cmp1),q1[t1=0]=b[0],i=1;i<cnt;i++)if(b[i].x!=b[i-1].x){
        while(t1&&(ll)(q1[t1].y-q1[t1-1].y)*(b[i].x-q1[t1].x)<=(ll)(b[i].y-q1[t1].y)*(q1[t1].x-q1[t1-1].x))t1--;
        q1[++t1]=b[i];
      }
      for(std::sort(b,b+cnt,cmp2),q2[t2=0]=b[0],i=1;i<cnt;i++)if(b[i].x!=b[i-1].x){
        while(t2&&(ll)(q2[t2].y-q2[t2-1].y)*(b[i].x-q2[t2].x)>=(ll)(b[i].y-q2[t2].y)*(q2[t2].x-q2[t2-1].x))t2--;
        q2[++t2]=b[i];
      }
      for(i=r;i>mid;i--)if(a[i].q){
        now=P(a[i].a,a[i].b),C=a[i].c;
        if(a[i].b>0)askmin2(ans1[i]),askmax1(ans2[i]);else askmin1(ans1[i]),askmax2(ans2[i]);
      }
    }
    int main(){
      read(n),read(m);
      for(i=1;i<=n;i++)read(A),read(B),a[i]=Q(A,B,0,0);
      for(i=1;i<=m;i++){
        read(op),read(A),read(B);
        if(op==1)a[n+i]=Q(A,B,0,0);else read(C),a[n+i]=Q(A,B,C,1);
        ans1[n+i]=inf,ans2[n+i]=-inf;
      }
      solve(1,n+=m);
      for(i=1;i<=n;i++)if(a[i].q)puts(ans2[i]<a[i].c||ans1[i]>a[i].c?"YES":"NO");
      return 0;
    }
    

      

  • 相关阅读:
    hdu1150&&POJ1325 Machine Schedule---最小点覆盖
    hdu-1068&&POJ1466 Girls and Boys---最大独立集
    hdu-2680 Choose the best route---dijkstra+反向存图或者建立超级源点
    hdu-1317 XYZZY---Floyd判连通+bellman最短路
    hdu-1874 畅通工程续---模板题
    hdu-2112 HDU Today---dijkstra+标号
    hdu-2066 一个人的旅行---模板题
    hdu-3790 最短路径问题---dijkstra两重权值
    hdu-2544 最短路---模板题
    BZOJ3529: [Sdoi2014]数表
  • 原文地址:https://www.cnblogs.com/clrs97/p/4434758.html
Copyright © 2011-2022 走看看