제출 #1127285

#제출 시각아이디문제언어결과실행 시간메모리
1127285RiverFlowTricks of the Trade (CEOI23_trade)C++20
100 / 100
1195 ms203872 KiB
#include <bits/stdc++.h> #define nl "\n" #define no "NO" #define yes "YES" #define fi first #define se second #define vec vector #define task "main" #define _mp make_pair #define ii pair<int, int> #define sz(x) (int)x.size() #define all(x) x.begin(), x.end() #define evoid(val) return void(std::cout << val) #define FOR(i, a, b) for(int i = (a); i <= (b); ++i) #define FOD(i, b, a) for(int i = (b); i >= (a); --i) #define unq(x) sort(all(x)); x.resize(unique(all(x)) - x.begin()) using namespace std; template<typename U, typename V> bool maxi(U &a, V b) { if (a < b) { a = b; return 1; } return 0; } template<typename U, typename V> bool mini(U &a, V b) { if (a > b) { a = b; return 1; } return 0; } const int N = (int)250000 + 9; const int mod = (int)1e9 + 7; void prepare(); void main_code(); int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen(task".inp", "r")) { freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } const bool MULTITEST = 0; prepare(); int num_test = 1; if (MULTITEST) cin >> num_test; while (num_test--) { main_code(); } } void prepare() {}; int n, k, c[N]; long long s[N]; int ver[N], vl[N]; const long long INF = (long long)-1e15; struct persis { struct node { int l, r; int cnt = 0; long long sum = 0; node () { l = r = -1; } void cp(node &x) { l = x.l, r = x.r; cnt = x.cnt; sum = x.sum; } }; int N; vector<node> t; int build(int l, int r) { int cur = sz(t); t.push_back(node()); if (l == r) return cur; int m = (l + r) >> 1; int L = build(l, m); int R = build(m + 1, r); t[cur].l = L, t[cur].r = R; // cerr << l << ' ' << r << ' ' << cur << ' ' << t[cur].l << ' ' << t[cur].r << nl; return cur; } void refine(int id){ t[id].cnt=t[t[id].l].cnt + t[t[id].r].cnt; t[id].sum=t[t[id].l].sum + t[t[id].r].sum; } int upd(int id, int l, int r, int p) { int cur = sz(t); t.push_back(node()); t.back().cp(t[id]); if (l == r) { ++t[cur].cnt; t[cur].sum += vl[l]; return cur; } int m = (l + r) >> 1; if (p <= m) { int x=upd(t[id].l, l, m, p); t[cur].l=x; }else{ int x=upd(t[id].r, m+1, r, p); t[cur].r=x; } refine(cur); // cerr << l << ' ' << r << ' ' << p << ' ' << id << ' ' << t[cur].l << ' ' << t[cur].r << ' ' << t[id].sum << nl; return cur; } int upd(int id, int v) { return upd(id, 1, N, v); } void init() { vec<int> cc; FOR(i, 1, n) cc.push_back(c[i]); unq(cc); N = sz(cc); FOR(i, 1, N) vl[i] = cc[i - 1]; ver[0] = build(1, N); FOR(i, 1, n) { int x = lower_bound(all(cc), c[i]) - cc.begin() + 1; ver[i] = upd(ver[i - 1], x); } } #define rc(id) (t[id].r) #define lc(id) (t[id].l) pair<long long, int> get(int id1, int id2, int l, int r, int k) { if (l == r) return _mp(1LL * k * vl[l], vl[l]); int m = (l + r) >> 1; if (t[rc(id1)].cnt - t[rc(id2)].cnt >= k) return get(rc(id1), rc(id2), m + 1, r, k); auto A = _mp(t[rc(id1)].sum - t[rc(id2)].sum, t[rc(id1)].cnt - t[rc(id2)].cnt); auto B = get(lc(id1), lc(id2), l, m, k - A.second); return _mp(A.fi + B.fi, B.se); } pair<long long, int> get(int l, int r) { if (r - l + 1 < k) return _mp(INF, 0); return get(ver[r], ver[l - 1], 1, N, k); } }; persis st; long long ans = INF; int opt[N]; long long dp[N]; void solve(int l, int r, int lb, int rb) { if (l > r) return ; int mid = (l + r) / 2; pair<long long, int> mx = {2LL * INF, -rb}; FOR(i, max(mid + k - 1, lb), rb) { mx = max(mx, _mp(st.get(mid, i).first - (s[i] - s[mid - 1]), -i)); } // cerr << l << ' ' << r << ' ' << lb << ' ' << rb << nl; dp[mid] = mx.first; opt[mid] = -mx.second; maxi(ans, dp[mid]); solve(l, mid - 1, lb, opt[mid]); solve(mid + 1, r, opt[mid], rb); } int res[N]; struct segment_tree { const int MX = (int)1e9 + 7; int n; vec<int> t; segment_tree () {}; segment_tree (int _n) { n = _n; t.resize(n * 4 + 7); FOR(i, 1, 4 * n) t[i] = MX; } void update(int id, int l, int r, int u, int v, int val) { if (l > v or r < u) return ; if (l >= u and r <= v) { t[id] = min(t[id], val); return ; } int m = (l + r) >> 1; update(id << 1, l, m, u, v, val); update(id << 1 | 1, m + 1, r, u, v, val); } void update(int l, int r, int val) { // cerr << l << ' ' << r << ' ' << val << nl; update(1, 1, n, l, r, val); // cerr << l << ' ' << r << ' ' << val << nl; } void fin(int id, int l, int r) { if (l == r) { res[l] = c[l] >= t[id]; return ; } t[id << 1] = min(t[id << 1], t[id]); t[id << 1 | 1] = min(t[id << 1 | 1], t[id]); int m = (l + r) >> 1; fin(id << 1, l, m); fin(id << 1 | 1, m + 1, r); } }; void main_code() { cin >> n >> k; FOR(i, 1, n) cin >> s[i], s[i] += s[i - 1]; FOR(i, 1, n) cin >> c[i]; st.init(); solve(1, n, 1, n); vec<int> p; FOR(i, 1, n) if (dp[i] == ans) { p.push_back(i); } // for(int x : p) cout << x << nl; segment_tree st2(n); FOR(i, 0, sz(p) - 2) { if (opt[p[i]] < p[i + 1]) { for(int j = opt[p[i]]; j <= opt[p[i+1]]; ++j) { auto g = st.get(p[i], j); long long x = g.first - (s[j] - s[p[i]-1]); if (x == ans) { st2.update(p[i], j, g.se); } } } else { for(int j = opt[p[i]]; j <= opt[p[i+1]]; ++j) { auto g = st.get(p[i], j); long long x = g.first - (s[j] - s[p[i]-1]); if (x == ans) { st2.update(p[i], j, g.se); } } } } FOR(j, opt[p.back()], n) { auto g = st.get(p.back(), j); long long x = g.first - (s[j] - s[p.back()-1]); if (x == ans) { st2.update(p.back(), j, g.se); } } cout << ans << nl; st2.fin(1, 1, n); FOR(i, 1, n) cout << res[i]; } /* Let the river flows naturally */

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

trade.cpp: In function 'int main()':
trade.cpp:36:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   36 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
trade.cpp:37:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   37 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...