没有大腿打CC是真的累
跟JOI这题一个套路
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=2010;
struct pt{
int x,y,c;
friend bool operator <(pt a,pt b){
return a.x<b.x || (a.x==b.x && a.y<b.y);
}
}p[N];
struct opt{
int a,b,dy,dx;
opt(){}
opt(int x,int y,int z,int w):a(x),b(y),dx(z),dy(w){}
friend bool operator <(opt a,opt b){
if(a==b) return a.b<b.b;
return 1LL*a.dy*b.dx<1LL*b.dy*a.dx;
}
friend bool operator ==(opt a,opt b){
return 1LL*a.dy*b.dx==1LL*a.dx*b.dy;
}
}s[N*N];
int t;
int n,m,b[N];
int mna[N<<2],mnb[N<<2],taga[N<<2],tagb[N<<2];
void build(int g,int l,int r){
mna[g]=mnb[g]=taga[g]=tagb[g]=0;
if(l==r) return ;
int mid=l+r>>1;
build(g<<1,l,mid); build(g<<1|1,mid+1,r);
}
inline void add(int g,int x,int y){
mna[g]+=x-y; mnb[g]+=y-x;
taga[g]+=x; tagb[g]+=y;
}
inline void Push(int g){
if(!taga[g] && !tagb[g]) return ;
add(g<<1,taga[g],tagb[g]); add(g<<1|1,taga[g],tagb[g]);
taga[g]=tagb[g]=0;
}
inline void Up(int g){
mna[g]=min(mna[g<<1],mna[g<<1|1]);
mnb[g]=min(mnb[g<<1],mnb[g<<1|1]);
}
void Add(int g,int l,int r,int L,int R,int x,int y){
if(l==L && R==r) return add(g,x,y);
int mid=L+R>>1; Push(g);
if(r<=mid) Add(g<<1,l,r,L,mid,x,y);
else if(l>mid) Add(g<<1|1,l,r,mid+1,R,x,y);
else Add(g<<1,l,mid,L,mid,x,y),Add(g<<1|1,mid+1,r,mid+1,R,x,y);
Up(g);
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int in=n,im=m;
for(int i=1;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y),p[i].c=0;
for(int i=n+1;i<=n+m;i++)
scanf("%d%d",&p[i].x,&p[i].y),p[i].c=1;
n+=m; sort(p+1,p+1+n); m=0;
for(int i=1;i<=n;i++) b[i]=i;
build(1,1,n);
for(int i=1;i<=n;i++){
if(p[i].c) Add(1,i,n,1,n,0,1);
else Add(1,i,n,1,n,1,0);
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
s[++m]=opt(i,j,p[j].x-p[i].x,p[j].y-p[i].y);
sort(s+1,s+1+m);
int ans=min(im+mna[1],in+mnb[1]);
/*int ans=1<<30,pa=0,pb=0;
for(int i=1;i<=n;i++){
if(p[i].c) pb++; else pa++;
ans=min(ans,min(pa,pb)+min(in-pa,im-pb));
}*/
for(int i=1,j;i<=m;i=j){
for(j=i;j<=m && s[i]==s[j];j++){
if(p[b[s[j].a]].c!=p[b[s[j].b]].c){
int l=b[s[j].a],r=b[s[j].b],pa=0,pb=0;
if(l>r) swap(l,r);
if(p[l].c==0) pa--; else pb--;
if(p[r].c==0) pa++; else pb++;
Add(1,l,r-1,1,n,pa,pb);
}
swap(p[b[s[j].a]],p[b[s[j].b]]),swap(b[s[j].a],b[s[j].b]);
}
ans=min(min(im+mna[1],in+mnb[1]),ans);
/*int pa=0,pb=0;
for(int k=1;k<=n;k++){
if(p[k].c) pb++; else pa++;
ans=min(ans,min(pa,pb)+min(in-pa,im-pb));
}*/
}
printf("%d\n",ans);
}
return 0;
}