QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#55056#1269. New EquipmentsYaoBIGTL 2ms3800kbC++174.8kb2022-10-12 07:22:112022-10-12 07:22:13

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-12 07:22:13]
  • 评测
  • 测评结果:TL
  • 用时:2ms
  • 内存:3800kb
  • [2022-10-12 07:22:11]
  • 提交

answer

#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i <= (n); i++)
#define revrep(i, a, n) for (auto i = n; i >= (a); i++)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a).size()
template<class T> bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } else return 0; }
using namespace std;

template<class A, class B> string to_string(pair<A, B> p);
template<class A> string to_string(A v) {
	bool first = 1;
	string res = "{";
	for (auto x: v) {
		if (!first) res += ", ";
		first = 0;
		res += to_string(x);
	}
	res += "}";
	return res;
}
template<class A, class B> string to_string(pair<A, B> p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

void debug_out() { cerr << endl; }
template<class H, class... T> void debug_out(H h, T... t) {
	cerr << " " << to_string(h);
	debug_out(t...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)


using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;

template<class Cap, class Cost, Cap Cap_MAX = numeric_limits<Cap>::max(), Cost Cost_MAX = numeric_limits<Cost>::max() / 4>
struct SuccessiveShortestPath {
	int n;
	struct E { int v; Cap a; Cost w; };
	vector<E> e;
	vector<vi> g;
	vector<Cost> h;

	SuccessiveShortestPath(int n): n(n), g(n), h(n) {}

	void add(int u, int v, Cap c, Cost w) {
		g[u].push_back(sz(e)); e.push_back({v, c, w});
		g[v].push_back(sz(e)); e.push_back({u, 0, -w});
	}

	vector<Cost> mincostflow(int src, int sink, Cap mx_flow = Cap_MAX) {
		// Run Bellman-Ford first if necessary.
		h.assign(n, Cost_MAX);
		h[src] = 0;
		rep(rd, 1, n) rep(now, 0, n - 1) for (auto i: g[now]) {
			auto [v, c, w] = e[i];
			if (c > 0) h[v] = min(h[v], h[now] + w);
		}
		// Bellman-Ford stops here.

		Cost cost = 0;
		Cap flow = 0;
		vector<Cost> res;
		while(mx_flow) {
			priority_queue<pair<Cost, int> > pq;
			vector<Cost> dis(n, Cost_MAX);
			dis[src] = 0; pq.emplace(0, src);
			
			vi pre(n, -1), mark(n, 0);
			while (sz(pq)) {
				auto [d, now] = pq.top(); pq.pop();
				// Using mark[] is safer than compare -d and dis[now] when the cost is float type.
				if (mark[now]) continue;
				mark[now] = 1;
				for (auto i: g[now]) {
					auto [v, c, w] = e[i];
					Cost off = dis[now] + w + h[now] - h[v];
					if (c > 0 && dis[v] > off) {
						dis[v] = off;
						pq.emplace(-dis[v], v);
						pre[v] = i;
					}
				}
			}
			if (pre[sink] == -1) break;
			
			rep(i, 0, n - 1) if (dis[i] != Cost_MAX) h[i] += dis[i];
			Cap aug = mx_flow;
			for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) aug = min(aug, e[i].a);
			for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) e[i].a -= aug, e[i ^ 1].a += aug;
			mx_flow -= aug;
			flow += aug;
			cost += aug * h[sink];
			res.push_back(cost);
		}
		return res;
	}
	// Calculate distance on residual graph
	Cost cal_dis(int st, int ed) {
		priority_queue<pair<Cost, int> > pq;
		vector<Cost> dis(n, Cost_MAX); 
		dis[st] = 0; pq.emplace(0, st);
		vi mark(n, 0);
		while (sz(pq)) {
			auto [d, now] = pq.top(); pq.pop();
			if (mark[now]) continue; // again, using mark is safe when C = double.
			mark[now] = 1;
			for (auto i: g[now]) {
				auto [v, c, w] = e[i];
				Cost off = dis[now] + w + h[now] - h[v];
				if (c > 0 && dis[v] > off) dis[v] = off, pq.emplace(-dis[v], v);
			}
		}
		return dis[ed] + h[ed] - h[st];
	}
};

int main() {
	ios::sync_with_stdio(0); cin.tie(0);

	int cas; cin >> cas; while (cas--) {
		int n, m; cin >> n >> m;
		vector<ll> as(n), bs(n), cs(n);
		rep(i, 0, n - 1) {
			cin >> as[i] >> bs[i] >> cs[i];
		}
		vector<ll> nums;

		rep(i, 0, n - 1) {
			ll a = as[i], b = bs[i];
			ll x0 = -b / (a * 2);
			chmin(x0, 1ll * m);
			chmax(x0, 1ll);
			vector<ll> pos;
			rep(j, 0, n + 5) if (x0 - j >= 1) pos.push_back(x0 - j);
			rep(j, 0, n + 5) if (x0 + j <= m) pos.push_back(x0 + j);
			sort(all(pos), [&](ll i, ll j) { return a * i * i + b * i < a * j * j + b * j; });
			pos.erase(unique(all(pos)), pos.end());
			if (sz(pos) > n) pos.resize(n);
			nums.insert(nums.end(), all(pos));
		}

		sort(all(nums));
		nums.erase(unique(all(nums)), nums.end());
		int tot = sz(nums);

		int N = n + tot;
		int src = N++, sink = N++;
		SuccessiveShortestPath<int, ll> mcmf(N);
		rep(i, 0, n - 1) mcmf.add(src, i, 1, 0);
		rep(i, 0, tot - 1) mcmf.add(i + n, sink, 1, 0);


		const ll off = 2e16;
		rep(i, 0, n - 1) {
			ll a = as[i], b = bs[i], c = cs[i];
			rep(j, 0, tot - 1){
				ll x = nums[j];
				mcmf.add(i, n + j, 1, a * x * x + b * x + c + off);
			}
		}
		auto res = mcmf.mincostflow(src, sink);
		rep(i, 0, n - 1) {
			ll x = res[i] - off * (i + 1);
			printf("%lld%c", x, " \n"[i == n - 1]);
		}
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 3800kb

input:

1
3 5
2 3 10
2 -3 10
1 -1 4

output:

4 15 37

result:

ok single line: '4 15 37'

Test #2:

score: -100
Time Limit Exceeded

input:

10
50 50
2 -16 79
8 -21 54
8 -1 3
1 -7 47
5 -20 89
1 -2 47
2 -10 26
10 31 28
2 -16 37
6 -16 44
2 -8 100
3 -26 65
3 -6 91
10 -33 56
2 -7 22
2 -12 74
1 -3 7
7 -30 51
1 -4 8
1 -10 62
2 -5 5
1 -3 38
7 -32 57
4 -24 65
1 -8 97
7 -28 71
5 -13 71
2 -14 49
6 -33 100
2 7 69
8 -22 38
5 -23 88
7 20 57
7 -11 83
...

output:


result: