제출 #1328127

#제출 시각아이디문제언어결과실행 시간메모리
1328127model_codeBitaro the Brave 3 (JOI25_brave3)C++20
100 / 100
727 ms197544 KiB
#include <bits/stdc++.h>
using namespace std;

void sorting(vector<long long>& t, vector<long long>& h, vector<long long>& p) {
	vector<tuple<long long, long long, long long>> tup;
	for (int i = 0; i < t.size(); i++) tup.push_back(make_tuple(t[i], h[i], p[i]));
	sort(tup.begin(), tup.end());
	for (int i = 0; i < t.size(); i++) t[i] = get<0>(tup[i]);
	for (int i = 0; i < t.size(); i++) h[i] = get<1>(tup[i]);
	for (int i = 0; i < t.size(); i++) p[i] = get<2>(tup[i]);
}

struct fraction {
	long long a, b;
};

struct node {
	char way;
	int par;
};

bool operator<(const fraction& p1, const fraction& p2) {
	if ((__int128)p1.a * (__int128)p2.b < (__int128)p1.b * (__int128)p2.a) return true;
	return false;
}


// ------------------------------------------------------------------------------------------------------
// --- solve function
// ------------------------------------------------------------------------------------------------------
vector<long long> solve(long long N, long long L, long long T, long long Q, vector<long long> t, vector<long long> h, vector<long long> p, vector<long long> m) {
	vector<long long> offset(L + 2, 0);
	vector<long long> slopes(L + 2, 0);
	sorting(t, h, p);

	// step 1. sort by p
	vector<pair<long long, int>> sorted;
	vector<int> indices(N, 0);
	for (int i = 0; i < N; i++) sorted.push_back(make_pair(p[i], i));
	sort(sorted.begin(), sorted.end());
	for (int i = 0; i < N; i++) indices[sorted[i].second] = i;

	// step 2. simulation
	for (int level = N - 1; level >= 0; level--) {
		long long keisuu = sorted[level].first - (level == 0 ? 0 : sorted[level - 1].first);

		// prepare
		vector<pair<fraction, int>> vec;
		for (int j = N - 1; j >= 0; j--) {
			if (indices[j] < level) continue;
			long long last_base = T, sum = 0;
			while (vec.size() >= 1) {
				long long base = (vec.size() == 1 ? T : t[vec[vec.size() - 2].second]);
				fraction new_frac = fraction{base - t[j], vec[vec.size() - 1].first.b + sum + h[j]};
				last_base = t[vec[vec.size() - 1].second];
				if (new_frac < vec[vec.size() - 1].first) { sum += vec[vec.size() - 1].first.b; vec.pop_back(); }
				else break;
			}
			if (vec.size() == 0) last_base = T;
			vec.push_back(make_pair(fraction{ last_base - t[j], sum + h[j]}, j));
		}

		// update slope
		for (int j = 0; j < vec.size(); j++) {
			long long lim = min(L + 1, vec[j].first.a / vec[j].first.b + 1);
			slopes[0] += keisuu * vec[j].first.b;
			slopes[lim] -= keisuu * vec[j].first.b;
			offset[lim] += keisuu * vec[j].first.a;
		}
	}
	for (int i = 1; i <= L + 1; i++) slopes[i] += slopes[i - 1];
	for (int i = 1; i <= L + 1; i++) offset[i] += offset[i - 1];

	// step 3. get answer
	vector<pair<long long, int>> query;
	vector<long long> answer(Q, L);
	long long total_price = 0;
	for (int i = 0; i < N; i++) total_price += h[i] * p[i];
	for (int i = 0; i < Q; i++) query.push_back(make_pair(m[i], i));
	sort(query.begin(), query.end());
	int qcount = 0;
	for (int i = 0; i <= L; i++) {
		long long money = 1LL * i * (total_price - slopes[i]) - offset[i];
		while (qcount < Q && query[qcount].first < money) {
			answer[query[qcount].second] = i - 1;
			qcount++;
		}
	}

	// step 4. return
	return answer;
}

int main() {
	long long N, L, T; scanf("%lld%lld%lld", &N, &L, &T);
	vector<long long> t(N, 0);
	vector<long long> h(N, 0);
	vector<long long> p(N, 0);
	for (int i = 0; i < N; i++) scanf("%lld%lld%lld", &t[i], &h[i], &p[i]);
	long long Q; scanf("%lld", &Q);
	vector<long long> m(Q, 0);
	for (int i = 0; i < Q; i++) scanf("%lld", &m[i]);
	vector<long long> ret = solve(N, L, T, Q, t, h, p, m);
	for (int i = 0; i < Q; i++) printf("%lld\n", ret[i]);
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

Main.cpp: In function 'int main()':
Main.cpp:95:33: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   95 |         long long N, L, T; scanf("%lld%lld%lld", &N, &L, &T);
      |                            ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:99:42: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   99 |         for (int i = 0; i < N; i++) scanf("%lld%lld%lld", &t[i], &h[i], &p[i]);
      |                                     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:100:27: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  100 |         long long Q; scanf("%lld", &Q);
      |                      ~~~~~^~~~~~~~~~~~
Main.cpp:102:42: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |         for (int i = 0; i < Q; i++) scanf("%lld", &m[i]);
      |                                     ~~~~~^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...