atcoder #082 E 暴力 计算几何

给出点集,然后求一个凸包的所有的子凸包的贡献总和,贡献计算是凸包内部含边界上点的数量N,凸包的不包含边界的顶点数S,贡献为$2^{N-S}$

首先很容易想到,凸包上包含内部的所有点构成的子凸包有Sum(i = 3 ->N)C(i,N)种情况,这个式子其实就是二项式的一部分。但是有可能出现多点共线的不合法情况,所以问题转换为求所有点构成的直线中,每条直线上大于2点的点的数目,每条直线都要分别计算,最后减去就行了。求共线可以用叉积可以用斜率,注意判重。

这场比赛迟了10分钟才写,这题开始还在用凸包搞,简直蠢(

/** @Date    : 2017-09-02 20:30:47
  * @FileName: C.cpp
  * @Platform: Windows
  * @Author  : Lweleth ([email protected])
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 210;
const double eps = 1e-6;
const LL mod = 998244353;

LL fa[210], inv[210];

LL fpow(LL a, LL n)
{
    LL r = 1LL;
    while(n > 0)
    {
        if(n & 1)
            r = r * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return r;
}

void init()
{
    fa[0] = 1;
    inv[0] = 1;
    for(LL i = 1; i <= 200; i++)
    {
        fa[i] = fa[i-1] * i % mod;
        inv[i] = fpow(fa[i], mod - 2);
    }
}

LL C(LL n, LL m)
{
    if(n < 0)
        return 0;
    n >>= 1;
    if(n == 0)
    	return 1LL;
    LL ans = 0;
    ans = ((fa[n + m] * inv[m] % mod)* inv[n]) % mod;
    return ans;
}

struct point
{
	double x, y;
	point(){}
	point(double _x, double _y){x = _x, y = _y;}
	point operator -(const point &b) const
	{
		return point(x - b.x, y - b.y);
	}
	double operator *(const point &b) const
	{
		return x * b.x + y * b.y;
	}
	double operator ^(const point &b) const
	{
		return x * b.y - y * b.x;
	}
	bool operator == (const point &b) const
	{
		return x==b.x && y==b.y;
	}

};

double xmult(point p1, point p2, point p0)
{
    return (p1 - p0) ^ (p2 - p0);
}  

double distc(point a, point b)
{
	return sqrt((double)((b - a) * (b - a)));
}
int sign(double x)
{
	if(fabs(x) < eps)
		return 0;
	if(x < 0)
		return -1;
	else
		return 1;
}

struct line
{
	point s, t;
	line(){}
	line(point ss, point tt){
		s = ss, t = tt;
	}
};

////////
int n;
point stk[N];
point p[N];

int cmpC(point a, point b)//水平序排序
{
	return sign(a.x - b.x) < 0 || (sign(a.x - b.x) == 0 && sign(a.y - b.y) < 0);
}

int Graham()//水平序
{
	sort(p, p + n, cmpC);
	int top = 0;
	for(int i = 0; i < n; i++)
	{
		while(top >= 2 && sign(xmult(stk[top - 2], stk[top - 1], p[i])) < 0)
			top--;
		stk[top++] = p[i];
	}
	int tmp = top;
	for(int i = n - 2; i >= 0; i--)
	{
		while(top > tmp && sign(xmult(stk[top - 2],stk[top - 1] ,p[i] )) < 0)
			top--;
		stk[top++] = p[i];
	}
	if(n > 1)
		top--;
	return top;
}

LL check(int m)
{
	//cout << m << endl;
	LL c = 2;
	LL t = 0;
	for(int i = 1; i < m; i++)
	{
		if(sign(xmult(stk[i - 1], stk[(i + 1)%(m)], stk[i])) == 0)
			c++;
		else t = (t + fpow(2, c) - (1LL + c + c * (c - 1) / 2LL) + mod) % mod, c = 2;
		//cout << c << endl;
	}
	if(c > 2)
		 t = (t + fpow(2, c) - (1LL + c + c * (c - 1) / 2LL) + mod) % mod;
	return t;
}

/////////
int main()
{

	while(~scanf("%d", &n))
	{
		for(int i = 0; i < n; i++)
		{
			double x, y;
			scanf("%lf%lf", &x, &y);
			p[i] = point(x, y);
		}
		LL ans = 0;
		LL cnt = Graham();
		//cout << cnt;
		//ans = (fpow(2, n) - check(cnt) - (1LL + n + (n - 1) * n / 2LL) + mod) % mod;
		ans = (fpow(2, n) - (1LL + n) + mod) % mod;
		for(int i = 0; i < n; i++)
		{
			map<LL, int>q;
			for(int j = i + 1; j < n; j++)
			{
				LL t;
				if(p[i].x == p[j].x)
					t = -1;
				else t = ((LL)(p[j].y - p[i].y) * fpow(p[j].x - p[i].x, mod - 2) % mod + mod ) % mod;
					q[t]++;
			}
			for(auto j : q)
			{
				ans -= fpow(2, j.se) - 1;
				ans %= mod;
			}
		}
		while(ans < 0)
			ans += mod;
		if(cnt > 2)
			printf("%lld\n", ans);
		else printf("0\n");
	}
    return 0;
}
时间: 2024-10-06 18:10:01

atcoder #082 E 暴力 计算几何的相关文章

【HDOJ】5128

暴力+计算几何. 1 /* 5128 */ 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 using namespace std; 8 9 typedef struct point { 10 int x, y; 11 point() {} 12 point(int xx, in

汕头市队赛 SRM14 T1 计算几何瞎暴力

计算几何瞎暴力 (easy.pas/c/cpp) 128MB 1s 在平面上,给定起点和终点,有一面墙(看作线段)不能穿过,问从起点走到终点的最短路程. 输入格式 输入一行,包含8个用空格分隔的整数xS,yS,xT,yT,x1,y1,x2,y2,依次表示起点(xS,yS),终点(xT,yT),线段(x1,y1)-(x2,y2). 输出格式 输出一个整数,表示答案四舍五入到整数后的值,保证答案精确值的小数点后一位不是4或5. 样例输入 1 1 2 2 1 2 2 1 样例输出 2 样例解释 走折线

LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力

二次联通门 : LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 /* LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 叫做计算几何 实则毒瘤数据结构 看到xor后 考虑Trie树 Trie树的每一个节点保存的是以当前子树中每个二进制位的个数 给Trie打一个全局xor标记,如果标记这一位是1,就交换它的两个儿子 另外维护一个前缀和 前缀和存的是没sort过的值的和 Trie维护的是sort之后的值 1操作直接在前缀和后加就好

BZOJ 1199 HNOI2005 汤姆的游戏 计算几何+暴力

题目大意:给定n个图形,每个图形可以是矩形或圆,m次询问某个点在多少个图形内部 将点按横坐标排序 对于每个图形,二分找到x值满足要求的区间,对于区间内每个点暴力 时间复杂度O(n^2) 数据范围25W 果然像hwd说的一样计算几何题数据范围出的这么大就是作死么= = #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm&

HDU 6697 Closest Pair of Segments (计算几何 暴力)

2019 杭电多校 10 1007 题目链接:HDU 6697 比赛链接:2019 Multi-University Training Contest 10 Problem Description The closest pair of points problem is a well-known problem of computational geometry. In this problem, you are given \(n\) points in the Euclidean plan

玲珑杯 round18 A 计算几何瞎暴力

题目链接 : http://www.ifrog.cc/acm/problem/1143 当时没看到坐标的数据范围= =看到讨论才意识到,不同的坐标最多只有1k多个,完全可以暴力做法,不过也要一些技巧. 首先注意数很大可能爆int,用LL得话注意强制转换或者全设为LL,假如  int a=50000,b=a;  LL sum=a*b; 则会爆出,除非ab都是LL 或者 sum=(LL)a*(LL)b; 还有就是R最大就是30,我们不妨设ans[i]表示R<=i的组合个数,做一个前缀和方便快速询问.

!HDU 4380 三角屋内有奇数个宝藏的三角形有多少个-计算几何-(向量叉乘&amp;线段与点的关系&amp;暴力枚举)

题意:小明要买三座房子,这三个房子构成一个三角形,已知n个房子的坐标,任何三个房子都不在一条直线上,又已知有m个宝藏的坐标,问房子构成的三角形内有奇数个宝藏的三角形有多少个.数据范围:n(3~100),m(1~1000) 分析: 简单的计算几何.记住这题的做法. 三角形内的点的个数=上面的线段下面的点的个数 -- 下面两条线段下面的点的个数(或者下面一条线段减上面两条线段,看具体位置情况,所以直接取绝对值就好) n个点有n(n-1)/2条线段,不超过1W,枚举每条线段,再枚举每个宝藏的坐标(10

“玲珑杯”ACM比赛 Round #18 A 计算几何你瞎暴力(瞎暴力)

题目链接:http://www.ifrog.cc/acm/problem/1143 题意:如果从一个坐标为 (x1,y1,z1)(x1,y1,z1)的教室走到(x2,y2,z2)(x2,y2,z2)的距离为 |x1−x2|+|y1−y2|+|z1−z2| 那么有多少对教室之间的距离是不超过R的呢? 题解:暴力暴力,把点记录在三维数组里面,然后暴力搜寻符合条件的点,值得注意的是在同个位置可能有不同的教室(明显不符合现实,蜜汁尴尬(逃.....) 不同位置直接暴力,会重复计算一次,比如点(1,2,3

HDU 5533 Dancing Stars on Me 计算几何瞎暴力

Dancing Stars on Me Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1184    Accepted Submission(s): 651 Problem Description The sky was brushed clean by the wind and the stars were cold in a b