最后就是這個題目需要注意的一點了,數(shù)據(jù)范圍給的特別大,顯然用 double 是不行的了,double 的精度也就只有 1e15 的樣子,所以所有的數(shù)據(jù)都需要用 long long 來儲存,然后好多好多地方的運算都會爆 long long ,需要暫時用 __int128 來進行運算,代碼中我用小寫的 ll 代替 __int128 ,大寫的 LL 代替的 long long
比較不錯的一道題目吧,做完之后收獲頗豐
代碼: ?
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<unordered_map>
using namespace std;typedef long long LL;typedef __int128 ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e3+100;const int mod=998244353;const int inv3=332748118;LL ans,not_ans,sumx[N<<1],sumy[N<<1];int n;inline int sgn(LL x){if(x==0)return 0;if(x < 0)return -1;else return 1;
}struct Point{LL x,y;Point(){}Point(LL _x,LL _y){x = _x;y = _y;}void input(){scanf("%lld%lld",&x,&y);}bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}bool operator < (Point b)const{return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;}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);}//叉積ll operator ^(const Point &b)const{return (ll)x*b.y - (ll)y*b.x;}//點積ll operator *(const Point &b)const{return (ll)x*b.x + (ll)y*b.y;}
}p[N],q[N<<1];inline int getxx(Point& a)
{if(sgn(a.x)>0 && sgn(a.y)>=0) return 1;if(sgn(a.x)<=0 && sgn(a.y)>0) return 2;if(sgn(a.x)<0 && sgn(a.y)<=0) return 3;if(sgn(a.x)>=0 && sgn(a.y)<0) return 4;
}bool cmp(Point a,Point b)
{if(getxx(a)!=getxx(b))return getxx(a)<getxx(b);return sgn(a^b)>0;
}void solve(int id)
{for(int i=1,j=1;i<=n;i++)if(i!=id)q[j++]=p[i]-p[id];sort(q+1,q+n,cmp);int n=::n-1;for(int i=1;i<=n;i++)q[i+n]=q[i];for(int i=1;i<=n<<1;i++){sumx[i]=(sumx[i-1]+q[i].x)%mod;sumy[i]=(sumy[i-1]+q[i].y)%mod;}int j=1,k=1,l=1;//相同極角的點的位置,銳角極角的位置,鈍角極角的位置for(int i=1;i<=n;i++){while(j<i+n&&(q[i]^q[j])==0&&(q[i]*q[j])>0)j++;k=max(k,j);while(k<i+n&&(q[i]^q[k])>0&&(q[i]*q[k])>0)k++;l=max(l,k);while(l<i+n&&(q[i]^q[l])>0)l++;LL x1=(sumx[k-1]-sumx[j-1]+mod)%mod;LL y1=(sumy[k-1]-sumy[j-1]+mod)%mod;ans=(ans+((q[i].x%mod)*(y1)-(x1)*(q[i].y%mod))%mod+mod)%mod;LL x2=(sumx[l-1]-sumx[k-1]+mod)%mod;LL y2=(sumy[l-1]-sumy[k-1]+mod)%mod;not_ans=(not_ans+((q[i].x%mod)*(y2)-(x2)*(q[i].y%mod))%mod+mod)%mod;}
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int w;cin>>w;while(w--){ans=0,not_ans=0;scanf("%d",&n);for(int i=1;i<=n;i++)p[i].input();for(int i=1;i<=n;i++)solve(i);printf("%lld\n",(ans-not_ans+mod-not_ans+mod)%mod*inv3%mod);}return 0;
}