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 = ;
int sgn(double x)
{
if (fabs(x) < eps)
return ;
if (x < )
return -;
return ;
}
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 < )
{
x = -x;
tx = true;
}
if (y < )
{
y = -y;
ty = true;
}
x %= mod;
y %= mod;
if (tx)
x = -x;
if (ty)
y = -y;
}
int getxx()
{
if (x > && y >= )
return ;
if (x <= && y > )
return ;
if (x < && y <= )
return ;
if (x >= && y < )
return ;
return ;
}
} a[maxn],del[maxn];
bool cmp(Point &a,Point &b){
if(a.getxx() != b.getxx()){
return a.getxx() < b.getxx();
}else{
return (a^b)>;
}
}
int n;
big ans;
void gao(int id){
Point now = a[id];
int m = ;
for(int i = ;i <= n;i++){
if(i==id)continue;
del[++m] = a[i]-now;
//del[m].Mod();
}
if(m<=)return;
sort(del+,del++m,cmp);
int p1 = ,p2 = ;
Point s1=del[],s2=del[],ts1,ts2;
for(int i = ;i <= m;i++){
int nxt;
while(true){
nxt = p1+;
if(nxt>m)nxt=;
if(nxt==i)break;
if(!((del[i]^del[nxt])>=&&(del[i]*del[nxt])>))break;
if((del[i]^del[nxt])==&&(del[i]^del[p1])!=)break;
p1=nxt;s1=s1+del[p1];
}
while(true){
nxt = p2+;
if(nxt>m)nxt=;
if(nxt==i)break;
if(!((del[i]^del[nxt])>=))break;
if((del[i]^del[nxt])==&&(del[i]^del[p2])!=)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+)/;
while (T--)
{
scanf("%d",&n);
ans=;
for (int i = ; i <= n; i++)
{
ll x, y;
scanf("%lld%lld",&x,&y);
a[i] = Point(x, y);
} for(int i= ;i <= n;i++){
gao(i);
}
ans=(ans*inv)%mod;
ll t = ans;
printf("%lld\n",t);
}
return ;
}

最新文章

  1. 第10章 Shell编程(2)_字符截取命令
  2. PHP的性能大坑--strtotime函数
  3. Uncaught RangeError: Maximum call stack size exceeded 超出最大调用值(个人解释)
  4. 获取SqlServer2005表结构(字段,主键,外键,递增,描述)
  5. matlab和C/C++混合编程--Mex (六)参数传递
  6. [转】HTTP请求流程(二)----Telnet模拟HTTP请求
  7. SqlServer 常用
  8. Jquery AJax Post 返回值问题
  9. apache ab的安装步骤
  10. java.imageIo给图片添加水印
  11. cordova安装--创建ionic项目
  12. C++断言assert
  13. Dos命令将合并两个文本文件的内容
  14. HTTP协议扫盲(四)HTTP协议进阶 - MIME类型
  15. pig limit 少于10行,会返回所有记录
  16. mongodb url
  17. Ionic3实现选项卡切换可以重新加载echarts
  18. centos7如何查看网络状态?
  19. 高效率php注意事项
  20. 组件 -- Alert

热门文章

  1. 白话算法:时间复杂度和大O表示法
  2. VMware 中的win7虚拟机在一段时间后就会自动挂起
  3. 2019-11-29-Roslyn-如何在-Target-引用-xaml-防止文件没有编译
  4. 设置SVC模式
  5. Linux下Eclipse里用gdb调试JNI里C/C++
  6. scp 自动带密码参数复制文件到主机
  7. thinkphp之session操作
  8. pyqt5-动画组QAnimationGroup
  9. JAVA笔记19-容器之三 Set接口、List接口、Collections类、Comparable接口(重要)
  10. c++string int转化简单写法