解法:我们离线一下,假设点集选择的点是
A
,
B
A,B
A,B,查询的点是
C
C
C,分两种情况。
第一种情况:
C
A
CA
CA垂直
A
B
AB
AB,那我们可以预处理所有以
A
A
A为起点的斜率,然后查询时根据斜率
C
A
CA
CA推出我们所需要的斜率,我们可以把所有的
C
i
C_{i}
Ci需要的斜率排序,所有的
A
B
i
AB_{i}
ABi排好序,然后双指针一次性求出以
A
B
i
AB_{i}
ABi为直角边对询问的总贡献。
第二种情况:
A
C
AC
AC垂直
B
C
BC
BC,我们枚举每个查询点
C
C
C,存好所有
A
i
C
、
B
i
C
A_{i}C、B_{i}C
AiC、BiC斜率,同时用另外一个数组存好与他们垂直的斜率,排好序,再一次双指针求出点集所有点对点
C
C
C的贡献。
#include<bits/stdc++.h>
using namespace std;constint maxn =2001;struct node {int x, y, id;
bool operator <(const node &t)const{if(x == t.x)return y < t.y;return x < t.x;};
bool operator ==(const node& t)const{if(x == t.x && y == t.y)return1;return0;}};
node A[maxn], B[maxn], AA[maxn], BB[maxn];int cnt[maxn], d[maxn], inf =2e9+1;int X[maxn], Y[maxn], ans[maxn], XX[maxn], YY[maxn];
node gao(int x,int y,int id){if(!x)return node{0, inf, id};if(!y)return node{0,0, id};int gcd =__gcd(x, y);
x /= gcd, y /= gcd;if(x <0)
x =-x, y =-y;return node{x, y, id};}intcalc(int n){int P =1, res =0;for(int i =1; i <= n; i++){
d[i]=0;while(P <= n && BB[P]< AA[i])
P++;if(i >1&& AA[i]== AA[i -1])
d[i]= d[i -1];elsewhile(P <= n && AA[i]== BB[P])
d[i]++, P++;
res += d[i];}return res;}intmain(){int n, q, x, y;while(~scanf("%d%d",&n,&q)){for(int i =1; i <= n; i++)scanf("%d%d",&X[i],&Y[i]);for(int i =1; i <= q; i++){scanf("%d%d",&XX[i],&YY[i]);for(int j =1; j <= n; j++){int tx = XX[i]- X[j];int ty = YY[i]- Y[j];int ttx = tx, tty = ty;
AA[j]=gao(ttx, tty,0);if(!tx)
BB[j]=gao(1,0, i);elseif(!ty)
BB[j]=gao(0,1, i);else
BB[j]=gao(-ty, tx, i);}sort(AA +1, AA +1+ n);sort(BB +1, BB +1+ n);
ans[i]=calc(n)/2;}for(int i =1; i <= n; i++){int tot =0;for(int j =1; j <= n; j++)if(i != j)
A[++tot]=gao(X[i]- X[j], Y[i]- Y[j],0);sort(A +1, A +1+ tot);int sz =0;for(int j =1; j < n; j++)if(A[j]== A[j -1]&& j >1)
cnt[sz]++;else
cnt[++sz]=1;unique(A +1, A +1+ tot);for(int j =1; j <= q; j++){int tx = XX[j]- X[i];int ty = YY[j]- Y[i];if(!tx)
B[j]=gao(1,0, j);elseif(!ty)
B[j]=gao(0,1, j);else
B[j]=gao(-ty, tx, j);}sort(B +1, B +1+ q);int P =1, Q =1;while(P <= sz && Q <= q){int cur = B[Q].id;if(A[P]== B[Q])
ans[cur]+= cnt[P], Q++;elseif(A[P]< B[Q])
P++;else
Q++;}}for(int i =1; i <= q; i++)printf("%d\n", ans[i]);}}
#include<bits/stdc++.h>#define ll long long
using namespace std;constint maxn =1e6+5;int f[maxn], d[maxn];
string s[2]={"Meiya","Takeru"};
string solve(){int n, u, v;
d[0]=2;
f[0]=-1;scanf("%d",&n);for(int i =1; i <= n; i++)
f[i]= d[i]=0;for(int i =2; i <= n; i++){scanf("%d",&u);
d[u]++;
f[i]= u;}int okk =0;for(int i =1; i <= n &&!okk; i++)if(!d[i]){if(d[f[i]]>1)
okk =1;int len =-1, v = i, cnt =0;while(v !=-1&& d[v]<=1){
v = f[v];
cnt++;if(d[v]>1)
len = cnt;}if(len >0&& len %2)
okk =1;}return s[okk];}intmain(){int T;scanf("%d",&T);while(T--)
cout<<solve()<<'\n';}