n<=2000,肯定没有办法把所有三角形找出来全判一遍
对于三角形的三个角,分别计算贡献,锐角的贡献是1倍面积,钝角的贡献是-2倍面积,这样算出角的贡献之后除以3就可以了
每次选择一个点为中心点,极角排序,维护一个锐角和钝角的坐标和,边扫边算贡献
#include <bits/stdc++.h> #define ll long long #define big __int128 #define eps 1e-8 #define mod 998244353 using namespace std; const int maxn = 2005; int sgn(double x) { if (fabs(x) < eps) return 0; if (x < 0) return -1; return 1; } struct Point { big x, y; Point() {} Point(big _x, big _y) { x = _x; y = _y; } Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); } Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); } big operator*(const Point &b) const { return x * b.x + y * b.y; } big operator^(const Point &b) const { return x * b.y - y * b.x; } void Mod() { bool tx = false, ty = false; if (x < 0) { x = -x; tx = true; } if (y < 0) { y = -y; ty = true; } x %= mod; y %= mod; if (tx) x = -x; if (ty) y = -y; } int getxx() { if (x > 0 && y >= 0) return 1; if (x <= 0 && y > 0) return 2; if (x < 0 && y <= 0) return 3; if (x >= 0 && y < 0) return 4; return 5; } } a[maxn],del[maxn]; bool cmp(Point &a,Point &b){ if(a.getxx() != b.getxx()){ return a.getxx() < b.getxx(); }else{ return (a^b)>0; } } int n; big ans; void gao(int id){ Point now = a[id]; int m = 0; for(int i = 1;i <= n;i++){ if(i==id)continue; del[++m] = a[i]-now; //del[m].Mod(); } if(m<=1)return; sort(del+1,del+1+m,cmp); int p1 = 1,p2 = 1; Point s1=del[1],s2=del[1],ts1,ts2; for(int i = 1;i <= m;i++){ int nxt; while(true){ nxt = p1+1; if(nxt>m)nxt=1; if(nxt==i)break; if(!((del[i]^del[nxt])>=0&&(del[i]*del[nxt])>0))break; if((del[i]^del[nxt])==0&&(del[i]^del[p1])!=0)break; p1=nxt;s1=s1+del[p1]; } while(true){ nxt = p2+1; if(nxt>m)nxt=1; if(nxt==i)break; if(!((del[i]^del[nxt])>=0))break; if((del[i]^del[nxt])==0&&(del[i]^del[p2])!=0)break; p2=nxt;s2=s2+del[p2]; } ts1=s1;ts2=s2-s1;ts1.Mod();ts2.Mod(); ans+=(del[i]^ts1);ans %= mod; ans-=(del[i]^ts2)%mod*2ll%mod; ans=(ans+mod)%mod; if(p1==i){p1++;s1=s1+del[p1];}s1=s1-del[i]; if(p2==i){p2++;s2=s2+del[p2];}s2=s2-del[i]; } } int main() { int T; scanf("%d",&T); big inv = (mod+1)/3; while (T--) { scanf("%d",&n); ans=0; for (int i = 1; i <= n; i++) { ll x, y; scanf("%lld%lld",&x,&y); a[i] = Point(x, y); } for(int i= 1;i <= n;i++){ gao(i); } ans=(ans*inv)%mod; ll t = ans; printf("%lld ",t); } return 0; }