CF55E-Very-Simple-Problem

讲道理的话,题目中有simple一词的题目都不会简单。。

这道题如果我们直接计算包含的个数,本蒟蒻只能想到$O(n^3)$的解法,然后就咕咕了。。于是我们可以从反面考虑——数不包含该点的三角形。然后我们发现,如果一个三角形不包含该点,则这个三角形总有一条边把该点和三角形另一个顶点分割开了,于是我们只需要枚举线段那个分割线段,然后求三角形另一个顶点有多少种选法即可,最后用总数减一下。

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 100005;

pair<long long, long long> a[2 * MAX_N];

inline long long dis(long long x1, long long y1, long long x2, long long y2,
long long x3, long long y3) {
return (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
}

inline bool in_poly(long long x, long long y, int n) {
long long area1 = 0, area2 = 0;
for (int i = 1; i <= n; ++i)
area1 += a[i].first * a[i + 1].second - a[i].second * a[i + 1].first;
for (int i = 1; i <= n; ++i)
area2 += fabs(
dis(x, y, a[i].first, a[i].second, a[i + 1].first, a[i + 1].second));
return fabs(area) == area2;
}

long long C3(int x) {
if (x < 3)
return 0;
return 1LL * x * (x - 1) * (x - 2) / 6;
}

long long C2(int x) {
if (x < 2)
return 0;
return 1LL * x * (x - 1) / 2;
}

long long solve(long long x, long long y, int n) {
if (!in_poly(x, y, n))
return 0;
int j = 2;
long long sum = 0;
for (int i = 1; i <= n; ++i) {
for (; dis(a[i].first, a[i].second, a[j + 1].first, a[j + 1].second, x, y) <
0;
++j)
;
sum += C2(j - i);
}
return C3(n) - sum;
}

int main() {
int n, t;
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i].first >> a[i].second;
for (int i = 1; i < n; ++i)
a[i + n] = a[i];
cin >> t;
for (int i = 1; i <= t; ++i) {
long long x, y;
cin >> x >> y;
cout << solve(x, y, n) << "\n";
}
return 0;
}

   转载规则


《CF55E-Very-Simple-Problem》 VinovnyyPoterpevshiy 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
GXOI/GZOI2019-旧词 GXOI/GZOI2019-旧词
相关链接(雾:[LNOI2014]LCA实际上这题就是加了一个幂。。原题爆破比赛 原题:当$k=1$时暴力:求LCA再求深度。。然后观察一下求LCA的方法。。最暴力的方法就是把根节点到节点$i$的路径上的点都打上标记,然后由节点$y$往上
2019-09-22
下一篇 
CF75E-Ship's-Shortest-Path CF75E-Ship's-Shortest-Path
计算几何方法存点、算边来建图,然后跑一边最短路就行了。这题水到Floyd都能过。。。 我们先连接起始点(s)和终点(t)。如果st不与多边形相交或与多边形的一条边重合,则直接输出st的长度。否则,建一个由s、t、st与多边形的两个交点、多边
2019-09-22
  目录