QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#439583#7520. Monster GeneratorMine_KingRE 0ms0kbC++143.5kb2024-06-12 12:52:372024-06-12 12:52:37

Judging History

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

  • [2024-06-12 12:52:37]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-06-12 12:52:37]
  • 提交

answer

// Think twice, code once.
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define eputchar(c) putc(c, stderr)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define eputs(str) fputs(str, stderr), putc('\n', stderr)
using namespace std;

int n;
long long m;
struct Line {
	long long k, b;

	Line() = default;
	Line(long long _k, long long _b): k(_k), b(_b) {}
} a[105], b[105];
struct node {long long ab, ak, bb, bk;} c[105];
unsigned long long ans;
vector<long long> tm;

double cross(Line a, Line b) {return (double)(b.b - a.b) / (a.k - b.k);}

int main() {
	freopen("yuanshen.in", "r", stdin);
	freopen("yuanshen.out", "w", stdout);
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%lld%lld%lld%lld", &a[i].b, &a[i].k, &b[i].b, &b[i].k);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			for (int p = 0; p < 2; p++)
				for (int q = 0; q < 2; q++) {
					if (i == j && p == q) continue;
					Line x = p ? b[i] : a[i], y = q ? b[j] : a[j];
					if (x.k == y.k) continue;
					tm.push_back((y.b - x.b + x.k - y.k - 1) / (x.k - y.k));
				}
	tm.push_back(0);
	sort(tm.begin(), tm.end());
	while (tm.back() > m) tm.pop_back();
	// for (long long i : tm) eprintf("%lld\n", i);
	// eputs("");
	reverse(tm.begin(), tm.end());
	while (tm.back() < 0) tm.pop_back();
	// return 0;
	reverse(tm.begin(), tm.end());
	tm.push_back(m + 1);
	tm.erase(unique(tm.begin(), tm.end()), tm.end());
	// //
	// tm.clear();
	// tm.push_back(0);
	// tm.push_back(1748);
	// tm.push_back(2426);
	// tm.push_back(2576);
	// tm.push_back(3493);
	// tm.push_back(4360);
	// tm.push_back(12197);
	// tm.push_back(m + 1);
	// //
	for (int t = 0; t + 1 < (int)tm.size(); t++) {
		long long tl = tm[t], tr = tm[t + 1] - 1;
		// eprintf("%lld %lld\n", tl, tr);
		for (int i = 1; i <= n; i++) c[i] = {a[i].b, a[i].k, b[i].b, b[i].k};
		sort(c + 1, c + n + 1, [&](const node &x, const node &y) {
			__int128 xa = x.ab + (__int128)x.ak * tl, xb = x.bb + (__int128)x.bk * tl;
			__int128 ya = y.ab + (__int128)y.ak * tl, yb = y.bb + (__int128)y.bk * tl;
			int opx = xa > xb, opy = ya > yb;
			return opx != opy ? opx < opy : (!opx ? xa < ya : xb > yb);
		});
		// for (int i = 1; i <= n; i++) eprintf("%lld ", c[i].bk);
		// eputs("");
		vector<Line> vec({Line(0, 0)});
		Line sum(0, 0);
		for (int i = 1; i <= n; i++) {
			sum.k -= c[i].ak, sum.b -= c[i].ab;
			vec.push_back(sum);
			sum.k += c[i].bk, sum.b += c[i].bb;
		}
		sort(vec.begin(), vec.end(), [](const Line &x, const Line &y) {
			return x.k != y.k ? x.k > y.k : x.b > y.b;
		});
		vector<Line> stk;
		for (Line l : vec) {
			while (!stk.empty()) {
				Line x = stk.back();
				stk.pop_back();
				if (x.k == l.k) continue;
				if (cross(x, l) <= 0) continue;
				if (stk.empty()) {stk.push_back(x); break;}
				if (cross(stk.back(), x) > cross(x, l)) continue;
				else {stk.push_back(x); break;}
			}
			stk.push_back(l);
		}
		for (int i = 0; i < (int)stk.size(); i++) {
			long long l, r;
			if (i > 0) l = max(tl, (long long)ceil(cross(stk[i - 1], stk[i])));
			else l = tl;
			if (i + 1 < (int)stk.size()) r = min(tr, (long long)floor(cross(stk[i], stk[i + 1])));
			else r = tr;
			if (l > r) continue;
			ans -= (unsigned long long)((__int128)(l + r) * (r - l + 1) / 2) * stk[i].k +
				(unsigned long long)(r - l + 1) * stk[i].b;
		}
	}
	printf("%llu\n", ans);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Dangerous Syscalls

input:

3 5
3 1 5 2
4 2 1 3
1 9 100 1

output:


result: