zoukankan      html  css  js  c++  java
  • bzoj2961&&bzoj4140 共点圆

    题目描述

      在平面直角坐标系中,Wayne需要你完成n次操作,操作只有两种:
      1.0 x y。表示在坐标系中加入一个以(x, y)为圆心且过原点的圆。
      2.1 x y。表示询问点(x, y)是否在所有已加入的圆的内部(含圆周),且至少在一个圆内部(含圆周)。
      为了减少你的工作量,题目保证圆心严格在x轴上方(纵坐标为正),且横坐标非零。


    输入格式

      第1行一个整数n。
      接下来n行,每行第一个数是0或1,分别表示两种操作。
      接着有两个实数x和y,具体意义见题面。


    输出格式

      对于每个询问操作,如果点在所有已加入的圆内(或圆周上),则输出“Yes”(不含引号);否则输出“No”(不含引号)。


    数据范围

           对于100%的数据,n≤500000,所有坐标绝对值不超过10000。 


    • 题解

      • 在一个圆内$(x-a)^2 + (y-b)^2 <=  x^2 + y^2$,化简得$ax + by >= frac{a^2 + b^2}{2}$,
      • 右边是定值,求出$ax+by$的最小值即可判断,做法类似bzoj3533
      • 如果对时间分治,每次对区间左边求凸包,$n logn$可以实现;
      • bzoj4140要求强制在线,可以采用二进制分组
      • 由于只会从后面查询,类似树状数组,每次重构末尾的$lowbit$位的凸包,查询不断-=lowbit(i)三分;
      • 注意复杂度的理解:
      • 考虑$n$位二进制数$N$,$lowbit$为第$i$位的有,$2^{n-i}$个,
      • $sum_{i=0}^{n-1} 2^i   *  2^{n-i} = N log_{2} N$
     1 #include<bits/stdc++.h>
     2 #define ld double
     3 #define il inline
     4 using namespace std;
     5 const int N=500010;
     6 const ld eps=1e-9;
     7 int n,m,st1[N],ed1[N],st2[N],ed2[N],top,cnt;
     8 ld mn;
     9 il int dcmp(ld x){return fabs(x)<eps?0:x<0?-1:1;}
    10 struct P{
    11     ld x,y;
    12     P(ld X=0,ld Y=0):x(X),y(Y){};
    13     bool operator <(const P&a)const{return fabs(x-a.x)<eps?y<a.y:x<a.x;}
    14     P operator -(const P&a)const{return P(x-a.x,y-a.y);}
    15 }q[N],p[N],t[N],Q; 
    16 ld crs(const P&a,const P&b){return a.x*b.y-a.y*b.x;}
    17 ld dot(const P&a,const P&b){return a.x*b.x+a.y*b.y;}
    18 void ask(int l,int r){
    19     while(r-l>=3){
    20         int mid=(r-l)/3,mid1=l+mid,mid2=r-mid;
    21         if(dot(q[mid1],Q)>dot(q[mid2],Q))l=mid1;
    22         else r=mid2;
    23     }
    24     for(int i=l;i<=r;++i)mn=min(mn,dot(q[i],Q));
    25 }
    26 int main(){
    27     #ifndef ONLINE_JUDGE 
    28     freopen("bzoj2961.in","r",stdin);
    29     freopen("bzoj2961.out","w",stdout);
    30     #endif
    31     scanf("%d",&n);
    32     for(int i=1,op;i<=n;++i){
    33         scanf("%d",&op);
    34         if(op==0){
    35             m++;scanf("%lf%lf",&p[m].x,&p[m].y);
    36             p[m].x+=cnt,p[m].y+=cnt;
    37             int l=m-(m&-m)+1,r=m;
    38             st1[m]=top=l;
    39             for(int j=l;j<=r;++j)t[j]=p[j];
    40             sort(t+l,t+r+1);
    41             q[top]=t[l];
    42             for(int j=l+1;j<=r;++j){
    43                 while(top>l&&dcmp(crs(q[top]-q[top-1],t[j]-q[top]))<=0)top--;
    44                 q[++top]=t[j];
    45             }
    46             int now=ed1[m]=st2[m]=top;
    47             for(int j=r-1;j>=l;--j){
    48                 while(top>now&&dcmp(crs(q[top]-q[top-1],t[j]-q[top]))<=0)top--;
    49                 if(j>l)q[++top]=t[j];
    50             }
    51             ed2[m]=top;
    52         }else{
    53             scanf("%lf%lf",&Q.x,&Q.y);
    54             Q.x+=cnt,Q.y+=cnt;
    55             if(!m){puts("No");continue;}
    56             mn = 1e18;
    57             for(int j=m;j;j-=j&-j){
    58                 if(Q.y>0)ask(st1[j],ed1[j]);
    59                 else ask(st2[j],ed2[j]),mn=min(mn,dot(Q,q[st1[j]]));
    60             }
    61             if(dcmp(mn*2-Q.x*Q.x-Q.y*Q.y)>=0)puts("Yes"),cnt++;
    62             else puts("No");
    63         }
    64     }
    65 }
    bzoj2961&&4140
  • 相关阅读:
    配置利用Tilcon 5.8 Radar Demo for vxWorks 6.8
    安装源REMI做源 CentOS上 PHP 的安装和升级
    产品苹果乔布斯和盖茨眼中真实的对方
    平台微软将死的平台:.Net
    企业生活12大颠覆性技术:移动互联网居首
    设备代工富士康加入Firefox OS阵营,下周将发布搭载Firefox OS的设备
    线程对象Android 开发之多线程处理、Handler 详解
    输出hadoop[置顶] hadoop之测试KMeans(二):输出结果分析
    个位数字poj 3126 Prime Path
    nullnullGet previous business day
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10280324.html
Copyright © 2011-2022 走看看