HDU 5033


单调队列。

多次询问,采用离线的方式,将Y设为0,即可。


typedef  long  long  LL ;
const   int  maxn = 200008 ;
typedef pair<int ,int> PII ;
vector< pair<int ,int> > g ;
const   double  pi = acos(-1.0) ;
pair<int ,int> Q[maxn] ;
double  ans[maxn] ;
int     c[maxn] ;

#define X first
#define Y second
int   down(PII a , PII b , PII c){ // c down ab
      return     abs((LL)a.Y - (LL)b.Y) * abs((LL)b.X - (LL)c.X)
             >=  abs((LL)b.Y - (LL)c.Y) * abs((LL)a.X - (LL)b.X) ;
}

double  angle(PII a , PII b){
       double c = atan(abs(a.Y - b.Y) * 1.0 / abs(+ a.X - b.X)) ;
       return 90.0 - c * 180.0 / pi ;
}

int   main(){

      int  i , j  , q , n , t , T = 1 ;
      pair<int , int> p ;

      cin>>t ;
      while(t--){
          cin>>n ;
          g.clear() ;

          for(i = 1 ; i <= n ; i++){
               scanf("%d%d" , &p.X , &p.Y) ;
               g.push_back(p) ;
          }

          cin>>q ;
          for(i = 0 ; i < q ; i++){
               scanf("%d" , &c[i])  ;
               g.push_back(make_pair(c[i] , 0)) ;
          }
          sort(g.begin() , g.end()) ;
          n = 0 ;
          for(i = 0  ; i < g.size() ; i++){
               p = g[i] ;
               if(p.Y == 0){
                    while(n-2>=0 && down(Q[n-2] , Q[n-1] , p)) n-- ;
                    ans[i] = angle(Q[n-1] , p) ;
               }
               else{
                    while(n > 0 && Q[n-1].Y <= p.Y) n-- ;
                    while(n-2>=0 && down(Q[n-2] , Q[n-1] , p)) n-- ;
                    Q[n++] = p ;
               }
          }

          n = 0 ;
          for(i = g.size() -1 ; i >= 0 ; i--){
               p = g[i] ;
               if(p.Y == 0){
                    while(n-2>=0 && down(Q[n-2] , Q[n-1] , p)) n-- ;
                    ans[i] += angle(Q[n-1] , p) ;
               }
               else{
                    while(n > 0 && Q[n-1].Y <= p.Y) n-- ;
                    while(n-2>=0 && down(Q[n-2] , Q[n-1] , p)) n-- ;
                    Q[n++] = p ;
               }
          }

          printf("Case #%d:\n" , T++) ;
          for(i = 0 ; i < q ; i++){
                j = lower_bound(g.begin() , g.end() , make_pair(c[i] ,0) ) - g.begin() ;
                printf("%.10lf\n" , ans[j]) ;
          }
      }
      return 0 ;
}


你可能感兴趣的:(HDU 5033)