Submission #392202

#TimeUsernameProblemLanguageResultExecution timeMemory
392202BorisBarcaSplit the sequence (APIO14_sequence)C++14
71 / 100
2089 ms48160 KiB
/* $$$$$$$\ $$\ $$$$$$$\ $$ __$$\ \__| $$ __$$\ $$ | $$ | $$$$$$\ $$$$$$\ $$\ $$$$$$$\ $$ | $$ | $$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$$\ |$$ __$$\ $$ __$$\ $$ |$$ _____|$$$$$$$\ | \____$$\ $$ __$$\ $$ _____|\____$$\ $$ __$$\ $$ / $$ |$$ | \__|$$ |\$$$$$$\ $$ __$$\ $$$$$$$ |$$ | \__|$$ / $$$$$$$ | $$ | $$ |$$ | $$ |$$ | $$ | \____$$\ $$ | $$ |$$ __$$ |$$ | $$ | $$ __$$ | $$$$$$$ |\$$$$$$ |$$ | $$ |$$$$$$$ |$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$\\$$$$$$$ | \_______/ \______/ \__| \__|\_______/ \_______/ \_______|\__| \_______|\_______| */ #include <bits/stdc++.h> #include <ext/pb_ds/detail/standard_policies.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; #define PB push_back #define MP make_pair #define INS insert #define LB lower_bound #define UB upper_bound #define pii pair <int,int> #define pll pair <long long, long long> #define X first #define Y second #define _ << " " << #define sz(x) (int)x.size() #define all(a) (a).begin(),(a).end() #define FOR(i, a, b) for (int i = (a); i < (b); ++i) #define FORD(i, a, b) for (int i = (a); i > (b); --i) #define FORA(i, x) for (auto &i : x) #define REP(i, n) FOR(i, 0, n) #define BITS(x) __builtin_popcount(x) #define SQ(a) (a) * (a) #define TRACE(x) cout << #x " = " << (x) << '\n'; #define YES cout << "YES\n" #define NO cout << "NO\n" #define umap unordered_map typedef long long ll; typedef long double ld; typedef vector <int> vi; typedef vector <pii> vpi; typedef vector <ll> vll; typedef vector <pll> vpl; typedef vector <string> vs; const int MOD = 1e9 + 7; const double PI = acos(-1); const int INF = 1e9 + 10; const ll INFL = 1e18 + 10; const int ABC = 30; inline int sum(int a, int b){ if (a + b < 0) return (a + b + MOD) % MOD; return (a + b) % MOD; } inline void add(int &a, int b){ a = sum(a, b); } inline int mul(ll a, ll b){ return ((a % MOD) * ((ll)b % MOD)) % MOD; } inline int sub(int a, int b){ return (a - b + MOD) % MOD; } inline int fast_pot(ll pot, ll n){ ll ret = 1; while (n){ if (n & 1LL) ret = (ret * pot) % MOD; pot = (pot * pot) % MOD; n >>= 1LL; } return ret; } const int N = 2e5 + 10; ll n, k, a[N], pref[N], dp[2][N], ans[202][100005]; ll get(int l, int r){ return pref[r] - (l ? pref[l - 1] : 0); } /* ll dp(int i, int j){ if (i == -1){ if (j == 0) return 0; return -INFL; } if (j == 0) return 0; ll &ret = memo[i][j]; if (~ret) return ret; for (int l = i; l >= 0; --l) ret = max(ret, dp(l - 1, j - 1) + get(l, i) * get(0, l - 1)); return ret; } void reconstruct(int i, int j){ if (i == -1) return; if (j == 0) return; for (int l = i; l >= 0; --l){ if (dp(l - 1, j - 1) + get(l, i) * get(0, l - 1) == dp(i, j)){ reconstruct(l - 1, j - 1); cout << l << ' '; return; } } }*/ struct Line{ mutable ll k, m, p, idx; bool operator<(const Line& o) const {return k < o.k; } bool operator<(ll x) const { return p < x; } }; struct LineContainer : multiset<Line, less<>> { ll div(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); } bool isect(iterator x, iterator y){ if (y == end()) return x->p = INFL, 0; if (x->k == y->k) x->p = x->m > y->m ? INFL : -INFL; else x->p = div(y->m - x->m, x->k - y->k); return x->p >= y->p; } void add(ll k, ll m, ll pos) { auto z = insert({k, m, 0, pos}), y = z++, x = y; while (isect(y, z)) y = 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)); } pll query(ll x){ assert(!empty()); auto l = *lower_bound(x); return {l.k * x + l.m, l.idx}; } }; int main () { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> k; FOR(i, 1, n + 1){ cin >> a[i]; pref[i] = (i ? pref[i - 1] : 0) + a[i]; } /*memset(memo, -1, sizeof memo); cout << dp(n - 1, k) << '\n'; reconstruct(n - 1, k); cout << '\n';*/ LineContainer cht; REP(i, n + 1) REP(j, 2) dp[j][i] = -INFL; dp[0][0] = 0; FOR(i, 1, n + 1) dp[1][i] = 0; FOR(j, 2, k + 2){ int x = j & 1; dp[0][0] = -INFL; cht.add(pref[j - 1], dp[x ^ 1][j - 1] - SQ(pref[j - 1]), j - 1); FOR(i, j, n + 1){ dp[x][i] = cht.query(pref[i]).X; ans[j][i] = cht.query(pref[i]).Y; //cout << j _ i _ ans[j][i] << '\n'; cht.add(pref[i], dp[x ^ 1][i] - SQ(pref[i]), i); } FOR(i, 0, n + 1) dp[x ^ 1][i] = -INFL; cht.clear(); } cout << dp[(k & 1) ^ 1][n] << '\n'; int idx = n; stack <int> s; for (int i = k + 1; i > 1; --i){ s.push(ans[i][idx]); idx = ans[i][idx]; } while (sz(s)){ int x = s.top(); cout << x << ' '; s.pop(); } cout << '\n'; return 0; }
#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...