【HDOJ6731】Angle Beats(极角排序)

题意:二维平面上给定n个整点,q个询问

每个询问给定另外的一个整点,问其能与n个整点中任意取2个组成的直角三角形的个数

保证所有点位置不同

n<=2e3,q<=2e3,abs(x[i],y[i])<=1e9

思路:

对于每个询问点q,分两类讨论

一:q为直角顶点

以q为原点,求出它到n个点的向量,极角排序

枚举一个向量,其贡献为平行于该向量逆时针转90度的向量的个数

二:q不为直角顶点

枚举直角顶点i作为原点,求出它到另外n-1个点的向量,极角排序

对于q,其贡献为:设t为i到q的向量,平行于t逆时针或顺时针转90度的向量的个数

用upper_bound-lower_bound计算个数

极度卡时,在HDOJ上TLE,在gym上4s时限3sA的

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  4100
 12 #define M  2000010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-6;
 29       int INF=1e9;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 
 34 struct P
 35 {
 36     int x,y;
 37     P()=default;
 38     P(int x,int y):x(x),y(y){}
 39     P rot90(){return P(-y,x);} //逆时针转90度
 40     P _rot90(){return P(y,-x);} //顺时针转90度
 41 }p[N],t[N];
 42 
 43 bool operator^(P a,P b) //叉积
 44 {
 45     return (1ll*a.x*b.y-1ll*a.y*b.x)>0;
 46 }
 47 
 48 int quadrant(P a)   //象限
 49 {
 50          if(a.x>0&&a.y>=0) return 1;
 51     else if(a.x<=0&&a.y>0) return 2;
 52     else if(a.x<0&&a.y<=0) return 3;
 53     else if(a.x>=0&&a.y<0) return 4;
 54 }
 55 
 56 bool operator<(P a,P b) //极角排序
 57 {
 58     int qa=quadrant(a),qb=quadrant(b);
 59     if(qa!=qb) return qa<qb;
 60     return a^b;
 61 }
 62 
 63 P operator-(P a,P b)
 64 {
 65     return P(a.x-b.x,a.y-b.y);
 66 }
 67 
 68 int ans[N],n,q;
 69 
 70 int read()
 71 {
 72    int v=0,f=1;
 73    char c=getchar();
 74    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 75    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 76    return v*f;
 77 }
 78 
 79 void solve()
 80 {
 81     rep(i,1,q) ans[i]=0;
 82     int m=n+q;
 83     rep(i,n+1,m)
 84     {
 85         int top=0;
 86         rep(j,1,n)
 87         {
 88             top++;
 89             t[top]=p[j]-p[i];
 90         }
 91         sort(t+1,t+top+1);
 92         rep(j,1,n)
 93         {
 94             P tmp=t[j].rot90();
 95             int num=upper_bound(t+1,t+top+1,tmp)-lower_bound(t+1,t+top+1,tmp);
 96             ans[i-n]+=num;
 97         }
 98     }
 99     rep(i,1,n)
100     {
101         int top=0;
102         rep(j,1,n)
103          if(j!=i)
104          {
105              top++;
106              t[top]=p[j]-p[i];
107          }
108         sort(t+1,t+top+1);
109         rep(j,n+1,m)
110         {
111             P tmp=p[j]-p[i];
112             P t1=tmp.rot90();
113             ans[j-n]+=upper_bound(t+1,t+top+1,t1)-lower_bound(t+1,t+top+1,t1);
114             P t2=tmp._rot90();
115             ans[j-n]+=upper_bound(t+1,t+top+1,t2)-lower_bound(t+1,t+top+1,t2);
116         }
117     }
118     rep(i,1,q) printf("%d\n",ans[i]);
119 }
120 
121 int main()
122 {
123     while(scanf("%d%d",&n,&q)!=EOF)
124     {
125         rep(i,1,n+q) p[i].x=read(),p[i].y=read();
126         solve();
127     }
128     return 0;
129 }

 

posted on 2019-10-22 18:21  myx12345  阅读(187)  评论(0编辑  收藏  举报

导航