枚举每个$S$作为原点,将所有$D$和$T$极角排序。
枚举每个$T$,那么另一个$T$需要和当前的$T$夹角不超过$180$度,贡献为内部$D$的个数。
双指针后用前缀和查询区间的贡献即可。
时间复杂度$O(n^2\log n)$。
#include<cstdio>
#include<algorithm>
const int N=810;
int D,S,T,i,j,k,cnt,s[N*4],f[N*4],g[N*4];long long ans;
struct P{
int x,y,t;
P(){}
P(int _x,int _y,int _t){x=_x,y=_y,t=_t;}
int sgn()const{return x?x>0:y>0;}
}a[N],b[N],c[N],e[N*4];
inline bool cmp(const P&a,const P&b){
if(a.sgn()!=b.sgn())return a.sgn()<b.sgn();
return 1LL*a.x*b.y<1LL*a.y*b.x;
}
int main(){
scanf("%d",&D);
for(i=1;i<=D;i++)scanf("%d%d",&a[i].x,&a[i].y);
scanf("%d",&S);
for(i=1;i<=S;i++)scanf("%d%d",&b[i].x,&b[i].y);
scanf("%d",&T);
for(i=1;i<=T;i++)scanf("%d%d",&c[i].x,&c[i].y);
for(i=1;i<=S;i++){
cnt=0;
for(j=1;j<=D;j++)e[++cnt]=P(a[j].x-b[i].x,a[j].y-b[i].y,0);
for(j=1;j<=T;j++)e[++cnt]=P(c[j].x-b[i].x,c[j].y-b[i].y,1);
std::sort(e+1,e+cnt+1,cmp);
for(j=1;j<=cnt;j++)e[j+cnt]=e[j];
for(j=1;j<=cnt*2;j++){
s[j]=s[j-1],f[j]=f[j-1],g[j]=g[j-1];
if(e[j].t)f[j]++,g[j]+=s[j];else s[j]++;
}
for(j=k=1;j<=cnt;j++)if(e[j].t){
if(k<j)k=j;
while(k+1<j+cnt&&1LL*e[j].x*e[k+1].y<=1LL*e[j].y*e[k+1].x)k++;
ans+=g[k]-g[j]-s[j]*(f[k]-f[j]);
}
}
return printf("%lld",ans),0;
}