QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#96967#6324. Expanded HullappleseWA 117ms3876kbC++149.6kb2023-04-16 12:23:552023-04-16 12:23:57

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-16 12:23:57]
  • 评测
  • 测评结果:WA
  • 用时:117ms
  • 内存:3876kb
  • [2023-04-16 12:23:55]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define double long double
const double eps = 1e-12;
int Dcmp(double x) {
	return x < -eps ? -1 : x > eps ? 1 : 0;
}
struct Point {
	double x, y, z;
	Point(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}
	bool operator == (const Point &rhs) const {
		return Dcmp(x - rhs.x) == 0 && Dcmp(y - rhs.y) == 0 && Dcmp(z - rhs.z) == 0;
	}
	Point operator + (const Point &rhs) const {
		return Point(x + rhs.x, y + rhs.y, z + rhs.z);
	}
	Point operator - (const Point &rhs) const {
		return Point(x - rhs.x, y - rhs.y, z - rhs.z);
	}
	double operator * (const Point &rhs) const {
		return x * rhs.x + y * rhs.y + z * rhs.z;
	}
	Point operator ^ (const Point &rhs) const {
		return Point(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
	}
	Point operator * (const double &k) const {
		return Point(x * k, y * k, z * k);
	}
	Point operator / (const double &k) const {
		return Point(x / k, y / k, z / k);
	}
	double len2() {
		return x * x + y * y + z * z;
	}
	double len() {
		return sqrt(len2());
	}
	Point Unit() {
		return *this / len();
	}
};
int Cmp(Point a, Point b) {
	return Dcmp(a.z - b.z) == 0 ? Dcmp(a.x - b.x) == 0 ? Dcmp(a.y - b.y) < 0 : Dcmp(a.x - b.x) < 0 : Dcmp(a.z - b.z) < 0;
}
double Volume(Point a, Point b, Point c, Point d) {
	return ((b - a) ^ (c - a)) * (d - a);
}
struct Line {
	Point s, t;
	Line(Point s = Point(), Point t = Point()) : s(s), t(t) {}
};
vector<Line> vl;
namespace Hull {
	const int maxn = 205;
	struct Face {
		int a, b, c, ok;
	};
	int n;
	Point P[maxn];
	int num;
	Face F[8 * maxn];
	int g[maxn][maxn];
	double Dblcmp(Point p, Face f) {
		Point p1 = P[f.b] - P[f.a], p2 = P[f.c] - P[f.a], p3 = p - P[f.a];
		return (p1 ^ p2) * p3;
	}
	void Dfs(int p, int now);
	void Deal(int p, int a, int b) {
		int f = g[a][b];
		Face add;
		if(F[f].ok) {
			if(Dblcmp(P[p], F[f]) > eps) {
				Dfs(p, f);
			}
			else {
				add.a = b, add.b = a, add.c = p, add.ok = 1, g[p][b] = g[a][p] = g[b][a] = num, F[num ++] = add;
			}
		}
	}
	void Dfs(int p, int now) {
		F[now].ok = false;
		Deal(p, F[now].b, F[now].a);
		Deal(p, F[now].c, F[now].b);
		Deal(p, F[now].a, F[now].c);
	}
	bool Same(int s, int t) {
		Point &a = P[F[s].a], &b = P[F[s].b], &c = P[F[s].c];
		return Dcmp(Volume(a, b, c, P[F[t].a])) == 0 && Dcmp(Volume(a, b, c, P[F[t].b])) == 0 && Dcmp(Volume(a, b, c, P[F[t].c])) == 0;
	}
	void Create() {
		num = 0;
		Face add;
		int flag = 1;
		for(int i = 1; i < n; ++ i) {
			if(!(P[0] == P[i])) {
				swap(P[1], P[i]);
				flag = 0;
				break;
			}
		}
		if(flag)
			return;
		flag = 1;
		for(int i = 2; i < n; ++ i) {
			if(Dcmp(((P[1] - P[0]) ^ (P[i] - P[0])).len()) == 1) {
				swap(P[2], P[i]);
				flag = 0;
				break;
			}
		}
		if(flag)
			return;
		flag = 1;
		for(int i = 3; i < n; ++ i) {
			if(Dcmp(Volume(P[0], P[1], P[2], P[i]))) {
				swap(P[3], P[i]);
				flag = 0;
				break;
			}
		}
		if(flag)
			return;
		for(int i = 0; i < 4; ++ i) {
			add.a = (i + 1) % 4;
			add.b = (i + 2) % 4;
			add.c = (i + 3) % 4;
			add.ok = 1;
			if(Dblcmp(P[i], add) > 0)
				swap(add.b, add.c);
			g[add.a][add.b] = g[add.b][add.c] = g[add.c][add.a] = num;
			F[num ++] = add;
		}
		for(int i = 4; i < n; ++ i) {
			for(int j = 0; j < num; ++ j) {
				if(F[j].ok && Dblcmp(P[i], F[j]) > eps) {
					Dfs(i, j);
					break;
				}
			}
		}
		int tmp = num;
		num = 0;
		for(int i = 0; i < tmp; ++ i)
			if(F[i].ok)
				F[num ++] = F[i];
	}
	int vis[maxn][maxn];
	void Extract() {
		for(int i = 0; i < num; ++ i) {
			int p = F[i].a, q = F[i].b;
			if(Cmp(P[q], P[p]))
				swap(p, q);
			if(!vis[p][q])
				vis[p][q] = 1, vl.push_back(Line(P[p], P[q]));
			p = F[i].b, q = F[i].c;
			if(Cmp(P[q], P[p]))
				swap(p, q);
			if(!vis[p][q])
				vis[p][q] = 1, vl.push_back(Line(P[p], P[q]));
			p = F[i].a, q = F[i].c;
			if(Cmp(P[q], P[p]))
				swap(p, q);
			if(!vis[p][q])
				vis[p][q] = 1, vl.push_back(Line(P[p], P[q]));
		}
	}
}
int n;
long long k, ans[5];
const int maxn = 2005, lim = 200;
vector<int> add[maxn], del[maxn];
vector<Line> nowl;
set<int> s;
struct P2 {
	double x, y;
	P2(double x = 0, double y = 0) : x(x), y(y) {}
	bool operator == (const P2 &rhs) const {
		return Dcmp(x - rhs.x) == 0 && Dcmp(y - rhs.y) == 0;
	}
	bool operator < (const P2 &rhs) const {
		return Dcmp(x - rhs.x) == 0 ? Dcmp(y - rhs.y) < 0 : Dcmp(x - rhs.x) < 0;
	}
	P2 operator + (const P2 &rhs) const {
		return P2(x + rhs.x, y + rhs.y);
	}
	P2 operator - (const P2 &rhs) const {
		return P2(x - rhs.x, y - rhs.y);
	}
	double operator ^ (const P2 &rhs) const {
		return x * rhs.y - y * rhs.x;
	}
	P2 operator * (const double &k) const {
		return P2(x * k, y * k);
	}
	P2 operator / (const double &k) const {
		return P2(x / k, y / k);
	}
	double len2() {
		return x * x + y * y;
	}
};
int Left(const P2 &a, const P2 &b, const P2 &c) {
	return Dcmp((b - a) ^ (c - a)) >= 0;
}
P2 base;
vector<P2> Convex(vector<P2>a) {
	int n = a.size(), cnt = 0;
	if(n < 3)
		return a;
	base = a[0];
	for(auto p : a)
		if(make_pair(p.x, p.y) < make_pair(base.x, base.y))
			base = p;
	sort(a.begin(), a.end(), [](const P2 &a, const P2 &b) {
		int d = Dcmp((a - base) ^ (b - base));
		if(d)
			return d > 0;
		return (a - base).len2() < (b - base).len2();
	});
	vector<P2>res;
	for(int i = 0; i < n; ++ i) {
		while(cnt > 1 && Left(res[cnt - 2], a[i], res[cnt - 1]))
			-- cnt, res.pop_back();
		res.push_back(a[i]), ++ cnt;
	}
	return res;
}
long long Calc(int mul) {
	int nowlim = lim * mul;
	for(int i = 0; i <= 2 * nowlim; ++ i)
		add[i].clear(), del[i].clear();
	nowl.resize(vl.size());
// cerr << vl.size() << endl;
	for(int i = 0; i < (int)vl.size(); ++ i) {
		nowl[i] = Line(vl[i].s * mul, vl[i].t * mul);
// cerr << "L: " << endl;
// cerr << nowl[i].s.x << " " << nowl[i].s.y << " " << nowl[i].s.z << endl;
// cerr << nowl[i].t.x << " " << nowl[i].t.y << " " << nowl[i].t.z << endl;
		add[int(ceil(nowl[i].s.z)) + nowlim].push_back(i);
		del[int(floor(nowl[i].t.z)) + nowlim].push_back(i);
	}
	long long ans = 0;
	for(int i = 0; i <= 2 * nowlim; ++ i) {
		for(auto j : add[i])
			s.insert(j);
		vector<P2> v;
		v.clear();
		int z = i - nowlim;
		for(auto x : s) {
			int f = 0;
			if(Dcmp(nowl[x].s.z - z) == 0)
				v.push_back(P2(nowl[x].s.x, nowl[x].s.y)), f = 1;
			if(Dcmp(nowl[x].t.z - z) == 0)
				v.push_back(P2(nowl[x].t.x, nowl[x].t.y)), f = 1;
			if(!f) {
				assert(Dcmp(nowl[x].s.z - z) < 0 && Dcmp(nowl[x].t.z - z) > 0);
				Point p = nowl[x].s + (nowl[x].t - nowl[x].s) / (nowl[x].t.z - nowl[x].s.z) * (z - nowl[x].s.z);
				v.push_back(P2(p.x, p.y));
			}
		}
		if(!v.size())
			continue;
		sort(v.begin(), v.end());
		v.erase(unique(v.begin(), v.end()), v.end());
		v = Convex(v);
// cerr << "At z = " << z << ": Convex is ";
// for(auto p : v)
// 	cerr << "(" << p.x << ", " << p.y << ")" << endl;
// cerr << endl;
		int pos = 0, sz = v.size();
		for(int j = 1; j < sz; ++ j)
			if(v[pos] < v[j])
				pos = j;
		#define Pre(p) ((p + sz - 1) % sz)
		#define Nxt(p) ((p + 1) % sz)
		int upp = 0, dwp = 0;
		for(int x = -nowlim; x <= nowlim; ++ x) {
			while(upp != pos && Dcmp(v[Pre(upp)].x - x) <= 0)
				upp = Pre(upp);
			while(dwp != pos && Dcmp(v[Nxt(dwp)].x - x) <= 0)
				dwp = Nxt(dwp);
			int mx = -nowlim - 1, mn = nowlim + 1;
			if(Dcmp(v[upp].x - x) <= 0) {
				if(upp != pos) {
					P2 s = v[upp], t = v[Pre(upp)], w = s + (t - s) / (t.x - s.x) * (x - s.x);
					if(Dcmp(w.y - round(w.y)) == 0)
						mx = round(w.y);
					else
						mx = floor(w.y);
				}
				else if(Dcmp(v[upp].x - x) == 0) {
					double wy = v[upp].y;
					if(Dcmp(wy - round(wy)) == 0)
						mx = round(wy);
					else
						mx = floor(wy);
				}
			}
			if(Dcmp(v[dwp].x - x) <= 0) {
				if(dwp != pos) {
					P2 s = v[dwp], t = v[Nxt(dwp)], w = s + (t - s) / (t.x - s.x) * (x - s.x);
					if(Dcmp(w.y - round(w.y)) == 0)
						mn = round(w.y);
					else
						mn = ceil(w.y);
				}
				else if(Dcmp(v[dwp].x - x) == 0) {
					double wy = v[dwp].y;
					if(Dcmp(wy - round(wy)) == 0)
						mn = round(wy);
					else
						mn = ceil(wy);
				}
			}
			if(mn <= mx) {
// cerr << "At x = " << x << ": mn = " << mn << " mx = " << mx << endl;
				ans += max(0, mx - mn + 1);
			}
		}
		#undef Pre
		#undef Nxt
// cerr << ans << endl;
		for(auto j : del[i])
			s.erase(s.find(j));
	}
// cerr << "Multiply " << mul << ": ans = " << ans << endl;
	return ans;
}
const int mod = 998244353;
int Add(int x, int y) {
	return (x += y) >= mod ? x - mod : x;
}
int Sub(int x, int y) {
	return (x -= y) < 0 ? x + mod : x;
}
int Mul(int x, int y) {
	return 1ll * x * y % mod;
}
int Pow(int x, int y) {
	int res = 1;
	for(; y; x = Mul(x, x), y >>= 1)
		if(y & 1)
			res = Mul(res, x);
	return res;
}
int main() {
	scanf("%d%lld", &n, &k);
	for(int i = 0, x, y, z; i < n; ++ i) {
		scanf("%d%d%d", &x, &y, &z);
		Hull :: P[i] = Point(x, y, z);
	}
	Hull :: n = n;
	Hull :: Create();
// cerr << Hull :: num << endl;
	Hull :: Extract();
// for(auto l : vl)
// 	cerr << "(" << l.s.x << ", " << l.s.y << ", " << l.s.z << ") (" << l.t.x << ", " << l.t.y << ", " << l.t.z << ")" << endl;
	ans[0] = 1;
	// Calc(1);
	for(int i = 1; i <= 3; ++ i)
		ans[i] = Calc(i);
	if(k <= 3)
		printf("%lld\n", ans[k]);
	else {
		int ret = 0;
		for(int i = 0; i <= 3; ++ i) {
			int up = ans[i] % mod, dn = 1;
			for(int j = 0; j <= 3; ++ j) {
				if(i == j)
					continue;
				up = Mul(up, Sub(k % mod, j));
				dn = Mul(dn, Sub(i, j));
			}
			ret = Add(ret, Mul(up, Pow(dn, mod - 2)));
		}
		printf("%d\n", ret);
	}
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3724kb

input:

4 2
0 0 0
1 0 0
0 1 0
0 0 1

output:

10

result:

ok 1 number(s): "10"

Test #2:

score: 0
Accepted
time: 2ms
memory: 3732kb

input:

4 10000
0 0 0
1 0 0
0 1 0
0 0 1

output:

59878050

result:

ok 1 number(s): "59878050"

Test #3:

score: 0
Accepted
time: 3ms
memory: 3704kb

input:

8 314159265358979
5 -3 -3
-5 -3 -3
0 5 -3
0 0 10
4 2 6
-4 2 6
0 -5 6
0 0 -5

output:

152811018

result:

ok 1 number(s): "152811018"

Test #4:

score: 0
Accepted
time: 79ms
memory: 3780kb

input:

100 1
0 0 77
0 0 -195
0 0 -194
0 0 -112
0 0 -192
0 0 62
0 0 73
0 0 188
0 0 -150
0 0 -26
0 0 -164
0 0 -142
0 0 -90
200 1 0
0 0 50
0 0 111
0 0 -133
0 0 91
0 0 -70
0 0 46
0 0 175
-200 -67 0
0 0 128
0 0 170
0 0 76
0 0 -28
0 0 47
0 0 -196
0 0 45
0 0 -136
0 0 96
0 0 24
0 0 -29
0 0 -141
0 0 -84
0 0 -99
0 0...

output:

882531

result:

ok 1 number(s): "882531"

Test #5:

score: 0
Accepted
time: 85ms
memory: 3756kb

input:

82 333333333
98 99 168
-106 -105 -172
113 114 193
-13 -12 -17
-115 -114 -187
71 72 123
-70 -69 -112
95 96 163
-85 -84 -137
-28 -27 -42
-31 -30 -47
-200 -67 0
-121 -120 -197
-52 -51 -82
-112 -111 -182
110 111 188
44 45 78
86 87 148
104 105 178
-73 -72 -117
47 48 83
62 63 108
-103 -102 -167
56 57 98
1...

output:

767480931

result:

ok 1 number(s): "767480931"

Test #6:

score: 0
Accepted
time: 95ms
memory: 3876kb

input:

100 1
-63 -39 51
-36 -104 70
9 -77 34
115 -153 19
-161 141 10
157 -149 -4
-82 -92 87
14 114 -64
-176 -68 122
-7 -179 93
-182 200 -9
173 97 -135
0 -1 200
-83 -189 136
117 69 -93
-3 -113 58
183 -179 -2
-52 -184 118
-107 89 9
-24 -48 36
-111 87 12
-143 -173 158
-176 -78 127
-96 162 -33
147 -111 -18
-92...

output:

9771107

result:

ok 1 number(s): "9771107"

Test #7:

score: 0
Accepted
time: 117ms
memory: 3820kb

input:

100 1159111449
82 82 90
181 181 -85
70 70 -20
1 1 0
190 190 56
-83 -83 40
-89 -89 39
136 136 146
-195 -195 47
50 50 -99
-101 -101 -161
162 162 146
23 23 152
181 181 -91
-73 -73 -5
-105 -105 6
155 155 -136
152 152 -190
-33 -33 -137
55 55 41
3 3 -199
-168 -168 -177
-111 -111 115
171 171 8
131 131 123
...

output:

681451260

result:

ok 1 number(s): "681451260"

Test #8:

score: -100
Wrong Answer
time: 108ms
memory: 3696kb

input:

8 1
200 200 200
-200 -200 -200
200 -200 -200
-200 200 200
-200 200 -200
200 200 -200
200 -200 200
-200 -200 200

output:

64320801

result:

wrong answer 1st numbers differ - expected: '64481201', found: '64320801'