决策单调性 用分治或者单调栈
单调栈没打过 尴尬
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=1000005;
inline ll sqr(ll x){ return x*x; }
struct Point{
int x,y,idx;
void read(int i){
::read(x); ::read(y); idx=i;
}
friend ll dist(Point& A,Point &B){
return sqr(A.x-B.x)+sqr(A.y-B.y);
}
}P[N];
int n;
int ans[N];
bool cmp(int i,int j,int k){
ll x=dist(P[i],P[j]);
ll y=dist(P[i],P[k]);
if(j<i || j>i+n) x=-1LL<<60;
if(k<i || k>i+n) y=-1LL<<60;
return x==y?P[j].idx>P[k].idx:x<y;
}
inline void Solve(int l,int r,int a,int b){
if (l>r) return;
int mid=(l+r)>>1,dm=a;
for (int i=a+1;i<=b;i++) if(cmp(mid,dm,i)) dm=i;
ans[mid]=P[dm].idx;
Solve(l,mid-1,a,dm);
Solve(mid+1,r,dm,b);
}
int main()
{
int Q;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(Q);
while (Q--){
read(n); for (int i=1;i<=n;i++) P[i].read(i),P[n+i]=P[i];
Solve(1,n,1,n<<1);
for (int i=1;i<=n;i++)
printf("%d\n",ans[i]);
}
return 0;
}