zoukankan      html  css  js  c++  java
  • [bzoj2961] 共点圆

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

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

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

    Sample Input
    5
    0 2.0000 3.0000
    0 4.0000 1.0000
    1 1.000000 1.000000
    0 -3.0000 2.0000
    1 1.000000 1.000000

    Sample Output
    Yes
    No

      n≤500000,所有坐标绝对值不超过10000。

      输入数据保证圆心纵坐标为正,横坐标非零。

      CDQ分治..这几天重新学了一下发现自己还是不怎么会..

      首先问题可以变成,每次给个半平面,询问是否所有圆心都在它里面。

      具体该在上凸包还是下凸包查就看推出来的式子了..

      主要是这题数据范围有点大,CDQ的时候不能多带log...

      要线性建区间[l,mid]里点的凸包的话,得使[l,mid]里的点x坐标有序;要线性查询[mid+1,r]里所有询问的话,得让[mid+1,r]里询问的斜率有序;而输入顺序本身又有一维。。

      所以最开始按照斜率排一下序,每次分治时按输入顺序分到左右两边,先处理[l,mid],然后再建凸包处理[mid+1,r]里的询问,最后把[l,r]按照x坐标归并排序一下...就都满足了..

      如果每次建凸包不是重新建,而是把两个小的合成一个大的,似乎就不用想那么多了?

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<queue>
     8 #define ll long long
     9 #define ui unsigned int
    10 #define d double
    11 using namespace std;
    12 const int maxn=500023;const d eps=1e-7;
    13 struct zsq{bool ask;int id;d x,y,k;}q[maxn];
    14 struct zstb{int l,r;}stb[maxn],xtb[maxn];int tot;
    15 int st[maxn<<1],TOP,dl[maxn],tmpdl[maxn];
    16 int i,j,k,n,m;
    17 bool gg[maxn],ask[maxn];
    18  
    19 int ra,fh;char rx;
    20 inline int read(){
    21     rx=getchar(),ra=0,fh=1;
    22     while(rx!='-'&&(rx<'0'||rx>'9'))rx=getchar();
    23     if(rx=='-')fh=-1,rx=getchar();
    24     while(rx>='0'&&rx<='9')ra=ra*10+rx-48,rx=getchar();return ra*fh;
    25 }
    26  
    27 inline d getk(int a,int b){return (q[b].y-q[a].y)/(q[b].x-q[a].x);}
    28 inline bool istb(int a,int b,int c,bool isstb){
    29     if(isstb)return (q[c].x-q[b].x)*(q[b].y-q[a].y) > (q[b].x-q[a].x)*(q[c].y-q[b].y);
    30     else return (q[b].x-q[a].x)*(q[c].y-q[b].y) > (q[c].x-q[b].x)*(q[b].y-q[a].y);
    31 }
    32  
    33 inline bool check(int a,int b){//点b在圆a内 
    34     return q[a].x*q[a].x+q[a].y*q[a].y +eps > (q[a].x-q[b].x)*(q[a].x-q[b].x)+(q[a].y-q[b].y)*(q[a].y-q[b].y);
    35 }
    36 inline void buildtb(int x,int l,int r){
    37     int i;
    38      
    39     stb[x].l=TOP+1;
    40     for(i=l;i<=r;i++)if(!q[dl[i]].ask){
    41         while(TOP>stb[x].l&&!istb(st[TOP-1],st[TOP],dl[i],1))TOP--;
    42         if(TOP>=stb[x].l&&q[st[TOP]].x==q[dl[i]].x)
    43             if(q[dl[i]].y>q[st[TOP]].y)TOP--;else continue;
    44         st[++TOP]=dl[i];
    45     }stb[x].r=TOP;
    46      
    47     xtb[x].l=TOP+1;
    48     for(i=l;i<=r;i++)if(!q[dl[i]].ask){
    49         while(TOP>xtb[x].l&&!istb(st[TOP-1],st[TOP],dl[i],0))TOP--;
    50         if(TOP>=xtb[x].l&&q[st[TOP]].x==q[dl[i]].x)
    51             if(q[dl[i]].y<q[st[TOP]].y)TOP--;else continue;
    52         st[++TOP]=dl[i];
    53     }xtb[x].r=TOP;
    54 }
    55 void solve(int l,int r){
    56     if(l==r)return;
    57     int i,x=++tot,mid=l+r>>1,r1=l,r2=mid+1;
    58      
    59     for(i=l;i<=r;i++)if(q[dl[i]].id<=mid)tmpdl[r1++]=dl[i];else tmpdl[r2++]=dl[i];
    60     memcpy(dl+l,tmpdl+l,(r-l+1)<<2);solve(l,mid);
    61      
    62     TOP=0,buildtb(x,l,mid);int top1=stb[x].r,top2=xtb[x].l,now;
    63     if(stb[x].l<=stb[x].r)
    64     for(i=mid+1;i<=r;i++)if(q[now=dl[i]].ask&&!gg[q[now].id]&&q[now].y!=0){
    65         if(q[now].y<0){
    66             while(top1>stb[x].l&&getk(st[top1-1],st[top1])<=q[now].k)top1--;
    67             if(!check(st[top1],now))gg[q[now].id]=1;
    68         }else{
    69             while(top2<xtb[x].r&&getk(st[top2],st[top2+1])<=q[now].k)top2++;
    70             if(!check(st[top2],now))gg[q[now].id]=1;
    71         }
    72     }
    73     solve(mid+1,r);
    74      
    75     r1=l,r2=mid+1;
    76     for(i=l;i<=r;i++)tmpdl[i]=((q[dl[r1]].x<=q[dl[r2]].x&&r1<=mid)||r2>r)?dl[r1++]:dl[r2++];
    77     memcpy(dl+l,tmpdl+l,(r-l+1)<<2);
    78 }
    79  
    80 bool operator <(zsq a,zsq b){return a.k<b.k;}
    81 int main(){
    82     n=read();d mxx=-1e9,mnx=1e9;
    83     for(i=1;i<=n;i++){
    84         q[i].ask=ask[i]=read(),gg[i]=!q[i].ask,
    85         scanf("%lf%lf",&q[i].x,&q[i].y);
    86         if(!q[i].y){
    87             if(q[i].x>0)gg[i]=mnx*2+eps<=q[i].x;
    88             if(q[i].x<0)gg[i]=mxx*2>=eps+q[i].x;
    89         }else q[i].k=-q[i].x/q[i].y;
    90         if(!q[i].ask)mxx=max(mxx,q[i].x),mnx=min(mnx,q[i].x);
    91         q[i].id=dl[i]=i;
    92     }
    93     sort(q+1,q+1+n);
    94     solve(1,n);
    95     bool flag=0;
    96     for(i=1;i<=n;i++)if(!ask[i])flag=1;else puts((flag&&!gg[i])?"Yes":"No");
    97 }
    View Code
  • 相关阅读:
    oracle中Blob和Clob类型的区别
    为什么要分库分表
    Enable file editing in Visual Studio's debug mode
    SQL Server Dead Lock Log
    Debug .NET Framework Source
    SQL Server text field里面有换行符的时候copy到excel数据会散乱
    诊断和修复Web测试记录器(Web Test Recorder)问题
    Can't load Microsoft.ReportViewer.ProcessingObjectModel.dll
    'telnet' is not recognized as an internal or external command
    Linq to XML
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/6159865.html
Copyright © 2011-2022 走看看