zoukankan      html  css  js  c++  java
  • bzoj 2961

    根据“点在圆内”关系,列出点P(x0,y0)在圆C(x,y)内的关系:

    (x-x0)^2+(y-y0)^2 <= x^2+y^2

    化简得:

    2*x0*x+2*y0*y >= x0^2+y0^2

    然后我们就可以把一个点当成一条线,一个圆当成一个点,通过上面的表达式来转换,这样“点在圆内”的关系就转化成了“点在半平面内”的关系。这样原问题就转化成了不断的加点,然后询问是否所有点都在某个半平面中。

    这个东西因为“某一个点在不在半平面中”对”所有点都在半平面中“的答案贡献独立(前者拥有一票否决权),又没有强制在线,所以可以使用对时间分治的思想,以多一个log的复杂度将”边加点边询问问题“变成”先把所有点都加进去,再询问问题“,而后者可以在O(nlogn)时间复杂度内搞定,所以可以在O(nloglog)的时间复杂度内解决。

    这道题开始看错题的限制了,题目中限制的是圆心坐标的范围,没有限制询问点坐标的范围,所以就挂了。

      1 /**************************************************************
      2     Problem: 2961
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:6708 ms
      7     Memory:96872 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <vector>
     13 #include <algorithm>
     14 #define N 500010
     15 #define eps 1e-10
     16 using namespace std;
     17  
     18 int sg( double x ) { return (x>-eps)-(x<eps); }
     19 struct Vector {
     20     double x, y;
     21     void read() { 
     22         scanf( "%lf%lf", &x, &y ); 
     23     }
     24     Vector(){}
     25     Vector( double x, double y ):x(x),y(y){}
     26     Vector operator+( const Vector &b ) const { return Vector(x+b.x,y+b.y); }
     27     Vector operator-( const Vector &b ) const { return Vector(x-b.x,y-b.y); }
     28     Vector operator*( double b ) const { return Vector(x*b,y*b); }
     29     Vector operator/( double b ) const { return Vector(x/b,y/b); }
     30     double operator^( const Vector &b ) const { return x*b.y-y*b.x; }
     31     double operator&( const Vector &b ) const { return x*b.x+y*b.y; }
     32     double ang() { return atan2l(y,x); }
     33     bool operator<( const Vector &b ) const {
     34         return sg(x-b.x)<0 || (sg(x-b.x)==0 && sg(y-b.y)<0);
     35     }
     36 };
     37 typedef Vector Point;
     38 struct Line {
     39     Point p;
     40     Vector u;
     41     double ang;
     42     int id;
     43     bool ok;
     44     void read( int id ) {
     45         double x, y;
     46         double a, b, c;
     47         scanf( "%lf%lf", &x, &y );
     48         a=x+x, b=y+y;
     49         c=x*x+y*y;
     50  
     51         if( sg(a)==0 && sg(b)==0 ) {
     52             p.x = p.y = 0.0;
     53             u.x = 1.0;
     54             u.y = 0.0;
     55         } else {
     56             if( sg(a)!=0 ) 
     57                 p.x = c/a, p.y = 0.0;
     58             else
     59                 p.x = 0.0, p.y = c/b;
     60             u.x = -b, u.y = a;
     61             if( sg(u^(Point(0.0,0.0)-p))>=0 ) 
     62                 u.x=-u.x, u.y=-u.y;
     63         }
     64  
     65         ok = true;
     66         this->id = id;
     67         ang = u.ang();
     68     }
     69 };
     70 struct Job {
     71     int opt;
     72     Point pt;
     73     Line ln;
     74     void read( int id ) {
     75         scanf( "%d", &opt );
     76         if( opt==0 ) pt.read();
     77         else ln.read(id);
     78     }
     79 };
     80  
     81 int n;
     82 Job job[N];
     83 int ans[N];
     84 Point cvx[N]; 
     85 double lang[N];
     86  
     87 bool onleft( Line &l, Point &p ) {  //  <=
     88     return sg( l.u^(p-l.p) ) >= 0;
     89 }
     90 bool onleft( Point &a, Point &b, Point &p ) {   //  <
     91     return sg( (b-a)^(p-a) ) > 0;
     92 }
     93 int convex( vector<Point> &p ) {
     94     sort( p.begin(), p.end() );
     95     int n=p.size();
     96     int m;
     97     cvx[m=0] = p[0];
     98     for( int i=1; i<n; i++ ) {
     99         while( m>0 && !onleft(cvx[m-1],cvx[m],p[i]) ) m--;
    100         cvx[++m] = p[i];
    101     }
    102     int k=m;
    103     for( int i=n-2; i>=0; i-- ) {
    104         while( m>k && !onleft(cvx[m-1],cvx[m],p[i]) ) m--;
    105         cvx[++m] = p[i];
    106     }
    107     return m;   //  n>=2
    108 }
    109 void binary( int lf, int rg, vector<Point> &vp, vector<Line> &vn ) {
    110     if( lf==rg ) {
    111         if( job[lf].opt==0 ) 
    112             vp.push_back( job[lf].pt );
    113         else
    114             vn.push_back( job[lf].ln );
    115         return;
    116     }
    117     vector<Point> lvp;
    118     vector<Line> rvn;
    119     int mid=(lf+rg)>>1;
    120     binary( lf, mid, lvp, vn );
    121     binary( mid+1, rg, vp, rvn );
    122     //--
    123     Point kpt;
    124     if( lvp.empty() || rvn.empty() ) {
    125         //  do nothing
    126     } else if( lvp.size()==1 ) {
    127         for( int t=0; t<rvn.size(); t++ ) {
    128             if( !rvn[t].ok ) continue;
    129             if( !onleft(rvn[t],lvp[0]) ) 
    130                 rvn[t].ok = false;
    131         }
    132     } else {
    133         int n = convex( lvp );
    134         for( int t=0; t<n; t++ )
    135             lang[t] = (cvx[(t+1==n?0:t+1)]-cvx[t]).ang();
    136         int vid = 0;
    137         for( int t=0; t<n; t++ )
    138             if( lang[t]>lang[(t+1==n?0:t+1)] ) {
    139                 vid = (t+1==n?0:t+1);
    140                 break;
    141             }
    142         rotate( cvx, cvx+vid, cvx+n );
    143         rotate( lang, lang+vid, lang+n );
    144         for( int t=0; t<rvn.size(); t++ ) {
    145             if( !rvn[t].ok ) continue;
    146             int tt;
    147             if( rvn[t].ang<=lang[0] || rvn[t].ang>=lang[n-1] ) {
    148                 tt = 0;
    149             } else {
    150                 int lf=1, rg=n-1;
    151                 while( lf<rg ) {
    152                     int mid=(lf+rg)>>1;
    153                     if( lang[mid]>rvn[t].ang ) {
    154                         rg = mid;
    155                     } else {
    156                         lf = mid+1;
    157                     }
    158                 }
    159                 tt = lf;
    160             }
    161             int pt = tt==0?n-1:tt-1;
    162             int nt = tt==n-1?0:tt+1;
    163             if( !onleft(rvn[t],cvx[tt]) 
    164               ||!onleft(rvn[t],cvx[pt])
    165               ||!onleft(rvn[t],cvx[nt]) ) {
    166                 rvn[t].ok=false;
    167             }
    168         }
    169     }
    170     //--
    171     for( int t=0; t<lvp.size(); t++ )
    172         vp.push_back( lvp[t] );
    173     for( int t=0; t<rvn.size(); t++ )
    174         vn.push_back( rvn[t] );
    175 }
    176 int main() {
    177     scanf( "%d", &n );
    178     bool ok = false;
    179     for( int i=1; i<=n; i++ ) {
    180         job[i].read(i);
    181         job[i].ln.ok = ok;
    182         if( job[i].opt==0 ) ok=true;
    183     }
    184     vector<Line> vn;
    185     vector<Point> vp;
    186     binary( 1, n, vp, vn );
    187     for( int i=1; i<=n; i++ )
    188         ans[i] = -1;
    189     for( int t=0; t<vn.size(); t++ ) 
    190         ans[vn[t].id] = vn[t].ok;
    191     for( int i=1; i<=n; i++ ) {
    192         if( ans[i]==-1 ) continue;
    193         printf( "%s
    ", ans[i] ? "Yes" : "No" );
    194     }
    195 }
    View Code
  • 相关阅读:
    盘点开发中那些常用的MySQL优化
    刚入职!就遇到上亿(MySQL)大表的优化
    面试技巧|“唇枪舌剑”之十大招式
    rpc是什么?php中流行的rpc框架有哪些?
    使用 memory_limit 限制 PHP 进程的内存使用
    swoole查看子进程与主进程关系
    使用SecureCRT连接AWS的EC2(Linux系统)亲测可行
    substitute Simple JavaScript Template :
    git 简单图表
    jquery 队列
  • 原文地址:https://www.cnblogs.com/idy002/p/4455435.html
Copyright © 2011-2022 走看看