답안 #788552

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
788552 2023-07-20T10:53:29 Z hugo_pm Chorus (JOI23_chorus) C++17
61 / 100
7000 ms 3164 KB
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    	
    #define all(v) (v).begin(), (v).end()
    #define rall(v) (v).rbegin(), (v).rend()
    #define rep(i, a, b) for(int i = (a); i < (b); i++)
    #define sz(v) ((int)((v).size()))
    	
    template<typename T>
    void chmax(T &x, const T &v) { if (x < v) x = v; }
    template<typename T>
    void chmin(T &x, const T &v) { if (x > v) x = v; }
    	
    using pii = pair<int, int>;
    using vi = vector<int>;
    	
    string to_string(string s) { return s; }
    template <typename T> string to_string(T v) {
    	bool first = true;
    	string res = "[";
    	for (const auto &x : v) {
    		if (!first)
    			res += ", ";
    		first = false;
    		res += to_string(x);
    	}
    	res += "]";
    	return res;
    }
    	
    void dbg_out() { cout << endl; }
    template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) {
    	cout << ' ' << to_string(H);
    	dbg_out(T...);
    }
    	
    #ifdef DEBUG
    #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
    #else
    #define dbg(...)
    #endif
    	
    const int INF = 1e12;
    struct _Line {
    	mutable int k, m, p;
    	bool operator<(const _Line& o) const { return k < o.k; }
    	bool operator<(int x) const { return p < x; }
    };
     
    struct _LineContainer : multiset<_Line, less<>> {
    	// (for doubles, use inf = 1/.0, div(a,b) = a/b)
    	static const int inf = LLONG_MAX;
    	int div(int a, int b) { // floored division
    		return a / b - ((a ^ b) < 0 && a % b); }
    	bool isect(iterator x, iterator y) {
    		if (y == end()) return x->p = inf, 0;
    		if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
    		else x->p = div(y->m - x->m, x->k - y->k);
    		return x->p >= y->p;
    	}
    	void add(int k, int m) {
    		auto z = insert({k, m, 0}), y = z++, x = y;
    		while (isect(y, z)) z = erase(z);
    		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
    		while ((y = x) != begin() && (--x)->p >= y->p)
    			isect(x, erase(y));
    	}
    	int queryMax(int x, int& from) {
    		assert(!empty());
    		auto l = *lower_bound(x);
    		from = l.k;
    		return l.k * x + l.m;
    	}
    };
     
    struct LineContainer {
    	_LineContainer fs;
    	void add (int k, int m) { // kx+m
    		// -f(x) = -(kx+m) = (-k)x + (-m)
    		fs.add(-k, -m);
    	}
    	int min(int x, int& from) {
    		if (fs.empty()) return INF;
    		return -fs.queryMax(x, from);
    	}
    };
     
    int N, K;
    string S;
    // ferme[i] = nombre d'ouvrants avant Fi
    vector<int> ouvre, ferme;
    vector<int> cumuFerme;
    int coutExclus(int left, int right) {
    	if (left >= right) {
    		return 0;
    	}
    	int projExclus = min(right, ouvre[right-1]);
    	if (projExclus <= left) return 0;
    	return (projExclus - left)*(right) - (cumuFerme[projExclus] - cumuFerme[left]);
    }
    signed main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	
    	cin >> N >> K >> S;
    	{
    		int curOuvre = 0, curFerme = 0;
    		cumuFerme.push_back(0);
    		for (char c : S) {
    			if (c == 'A') {
    				++curOuvre;
    				ouvre.push_back(curFerme);
    			} else {
    				++curFerme;
    				ferme.push_back(curOuvre);
    				cumuFerme.push_back(cumuFerme.back() + curOuvre);
    			}
    		}
    	}
    	
    	auto calc = [&] (int lambda) -> pii {
    		vector<pii> dp(N+1, {INF, INF});
    		dp[N] = {0, 0};
    		LineContainer cont;
    		// [J EXCLUS]
    		// gright(left) = (projExclus - left)*(right) - (cumuFerme[projExclus] - cumuFerme[left])
    		// gj(x) = (pj - x)*j - (cf[pj] - cf[left])
    		// gj(x) = -jx + (j*pj - cf[pj]) + cf[x]
    		//         mx  + p               + terme fixe
    		auto proj = [&] (int j) {
    			return min(j, ouvre[j-1]);
    		};
    		auto add = [&] (int j) {
    			int pj = proj(j);
    			cont.add(-j, dp[j].first + j*pj - cumuFerme[pj]);
    		};
    		int jToAdd = N;
    		for (int left = N-1; left >= 0; --left) {
    			while (jToAdd > 0 && left <= min(proj(jToAdd), jToAdd-1)) {
    				add(jToAdd--);
    			}
    			rep(right, left+1, N+1) {
    				int prop = dp[right].first + coutExclus(left, right) + lambda;
    				chmin(dp[left], pii {prop, dp[right].second + 1});
    			}
    			// if (true) {
    			// 	int from = -1;
    			// 	int prop = cont.min(left, from) + cumuFerme[left] + lambda;
    			// 	if (dp[left].first > prop) {
    			// 		dp[left] = {prop, dp[from].second + 1};
    			// 	}
    			// }
    			// if (jToAdd > 0) {
    			// 	int prop = dp[jToAdd].first + coutExclus(left, jToAdd) + lambda;
    			// 	if (dp[left].first > prop) {
    			// 		dp[left] = {prop, dp[jToAdd].second + 1};
    			// 	}
    			// }
    		}
    		return dp[0];
    	};
    	int lo = 0, hi = INF;
    	while (lo < hi) {
    		int mid = (lo+hi) / 2;
    		if(calc(mid).second > K) {
    			lo = mid+1;
    		} else {
    			hi = mid;
    		}
    	}
    	assert(lo == hi);
    	int lambda = lo;
    	auto [score, groupsMade] = calc(lambda);
    	assert(groupsMade <= K);
    	cout << score - lambda*K << '\n';
    }
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 0 ms 212 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
13 Correct 1 ms 212 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 0 ms 212 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
13 Correct 1 ms 212 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 4 ms 332 KB Output is correct
18 Correct 19 ms 340 KB Output is correct
19 Correct 19 ms 364 KB Output is correct
20 Correct 15 ms 360 KB Output is correct
21 Correct 23 ms 356 KB Output is correct
22 Correct 24 ms 340 KB Output is correct
23 Correct 15 ms 356 KB Output is correct
24 Correct 18 ms 348 KB Output is correct
25 Correct 20 ms 344 KB Output is correct
26 Correct 19 ms 340 KB Output is correct
27 Correct 18 ms 340 KB Output is correct
28 Correct 18 ms 352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 0 ms 212 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
13 Correct 1 ms 212 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 4 ms 332 KB Output is correct
18 Correct 19 ms 340 KB Output is correct
19 Correct 19 ms 364 KB Output is correct
20 Correct 15 ms 360 KB Output is correct
21 Correct 23 ms 356 KB Output is correct
22 Correct 24 ms 340 KB Output is correct
23 Correct 15 ms 356 KB Output is correct
24 Correct 18 ms 348 KB Output is correct
25 Correct 20 ms 344 KB Output is correct
26 Correct 19 ms 340 KB Output is correct
27 Correct 18 ms 340 KB Output is correct
28 Correct 18 ms 352 KB Output is correct
29 Correct 1477 ms 792 KB Output is correct
30 Correct 1696 ms 708 KB Output is correct
31 Correct 1681 ms 748 KB Output is correct
32 Correct 1338 ms 692 KB Output is correct
33 Correct 1405 ms 708 KB Output is correct
34 Correct 1350 ms 848 KB Output is correct
35 Correct 1320 ms 852 KB Output is correct
36 Correct 1579 ms 660 KB Output is correct
37 Correct 1711 ms 796 KB Output is correct
38 Correct 1686 ms 836 KB Output is correct
39 Correct 1689 ms 728 KB Output is correct
40 Correct 1699 ms 764 KB Output is correct
41 Correct 1638 ms 616 KB Output is correct
42 Correct 1661 ms 664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 0 ms 212 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
13 Correct 1 ms 212 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 4 ms 332 KB Output is correct
18 Correct 19 ms 340 KB Output is correct
19 Correct 19 ms 364 KB Output is correct
20 Correct 15 ms 360 KB Output is correct
21 Correct 23 ms 356 KB Output is correct
22 Correct 24 ms 340 KB Output is correct
23 Correct 15 ms 356 KB Output is correct
24 Correct 18 ms 348 KB Output is correct
25 Correct 20 ms 344 KB Output is correct
26 Correct 19 ms 340 KB Output is correct
27 Correct 18 ms 340 KB Output is correct
28 Correct 18 ms 352 KB Output is correct
29 Correct 1477 ms 792 KB Output is correct
30 Correct 1696 ms 708 KB Output is correct
31 Correct 1681 ms 748 KB Output is correct
32 Correct 1338 ms 692 KB Output is correct
33 Correct 1405 ms 708 KB Output is correct
34 Correct 1350 ms 848 KB Output is correct
35 Correct 1320 ms 852 KB Output is correct
36 Correct 1579 ms 660 KB Output is correct
37 Correct 1711 ms 796 KB Output is correct
38 Correct 1686 ms 836 KB Output is correct
39 Correct 1689 ms 728 KB Output is correct
40 Correct 1699 ms 764 KB Output is correct
41 Correct 1638 ms 616 KB Output is correct
42 Correct 1661 ms 664 KB Output is correct
43 Execution timed out 7022 ms 3164 KB Time limit exceeded
44 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 1 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 0 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 0 ms 212 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 1 ms 212 KB Output is correct
13 Correct 1 ms 212 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 4 ms 332 KB Output is correct
18 Correct 19 ms 340 KB Output is correct
19 Correct 19 ms 364 KB Output is correct
20 Correct 15 ms 360 KB Output is correct
21 Correct 23 ms 356 KB Output is correct
22 Correct 24 ms 340 KB Output is correct
23 Correct 15 ms 356 KB Output is correct
24 Correct 18 ms 348 KB Output is correct
25 Correct 20 ms 344 KB Output is correct
26 Correct 19 ms 340 KB Output is correct
27 Correct 18 ms 340 KB Output is correct
28 Correct 18 ms 352 KB Output is correct
29 Correct 1477 ms 792 KB Output is correct
30 Correct 1696 ms 708 KB Output is correct
31 Correct 1681 ms 748 KB Output is correct
32 Correct 1338 ms 692 KB Output is correct
33 Correct 1405 ms 708 KB Output is correct
34 Correct 1350 ms 848 KB Output is correct
35 Correct 1320 ms 852 KB Output is correct
36 Correct 1579 ms 660 KB Output is correct
37 Correct 1711 ms 796 KB Output is correct
38 Correct 1686 ms 836 KB Output is correct
39 Correct 1689 ms 728 KB Output is correct
40 Correct 1699 ms 764 KB Output is correct
41 Correct 1638 ms 616 KB Output is correct
42 Correct 1661 ms 664 KB Output is correct
43 Execution timed out 7022 ms 3164 KB Time limit exceeded
44 Halted 0 ms 0 KB -