Submission #971195

#TimeUsernameProblemLanguageResultExecution timeMemory
971195_rain_Split the sequence (APIO14_sequence)C++14
100 / 100
1641 ms94480 KiB
/** author : _RAIN_ **/ #include<bits/stdc++.h> using namespace std; using i64 = long long; using ui64 = unsigned long long; #define MASK(x) ((i64)(1) << (x)) #define BIT(mask , x) (((mask) >> (x)) & (1)) template<class T> bool maximize(T &a , T b) {if (a < b) return a = b , true; else return false;} template<class T> bool minimize(T &a , T b) {if (a > b) return a = b , true; else return false;} template<class T> T gcd(T x , T y) {while (y) swap(y , x %= y); return x;} template<class T> T lcm(T x , T y) {return (x * y) / gcd(x , y);} #define sz(x) (int)((x).size()) struct Line { i64 a , b; Line(i64 a , i64 b) : a(a) , b(b) {}; }; struct Hull { Line X; long double intersec; int idx; }; class Convex_hull { public: vector<Hull> line; long double getintersec(Line x , Line y) { return (long double)(y.b - x.b) / (x.a - y.a); } i64 getval(Line a , i64 x) { return a.a * x + a.b; } void addline(Line a , int idx) { int n = sz(line); while (n > 1 && getintersec(line[n - 2].X , a) <= getintersec(line[n - 1].X , line[n - 2].X)) line.pop_back() , --n; if (!sz(line)) line.push_back({a , LLONG_MIN , idx}); else line.push_back({a , getintersec(a , line[n - 1].X), idx}); return; } pair<i64 , int> find(i64 val) { int low = 0 , high = sz(line) - 1 , p = 0; while (low <= high) { int mid = low + high >> 1; if (line[mid].intersec <= val) p = mid , low = mid + 1; else high = mid - 1; } return {getval(line[p].X , val) , line[p].idx}; } void add(i64 a , i64 b , int idx) { addline(Line{a , b} , idx); return; } }; const i64 limit = LLONG_MAX; const int maxn = 1e5; const int maxk = 200; i64 dp[maxn + 2] , g[maxn + 2] , a[maxn + 2] , pre[maxn + 2]; int trace[maxk + 2][maxn + 2]; int n , k; void solve(int idx) { Convex_hull bag1; for (int i = 1; i <= n; ++i) dp[i] = limit; for (int i = 1; i <= n; ++i) { if (bag1.line.size()) { pair<i64 , int> val = bag1.find(pre[i - 1]); dp[i] = val.first - pre[n] * pre[i - 1] + pre[i - 1] * pre[i - 1]; trace[idx][i] = val.second; } if (i > 1) { int j = 1; if (minimize(dp[i] , dp[1] - pre[n] * pre[i - 1] + pre[i - 1] * pre[i - 1] - pre[i - 1] * pre[j - 1] + pre[n] * pre[j - 1])) trace[idx][i] = 1; } bag1.add(-pre[i - 1] , pre[n] * pre[i - 1] + g[i] , i); } for (int i = 1; i <= n; ++i) g[i] = dp[i]; } int32_t main(void) { cin.tie(nullptr)->sync_with_stdio(false); const string name = "main"; if (fopen((name + ".inp").c_str() , "r")) { (void)!freopen((name + ".inp").c_str() , "r" , stdin); (void)!freopen((name + ".out").c_str() , "w+", stdout); } cin >> n >> k; int bug = 0; memset(pre , 0 , sizeof pre); for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 1; i <= n; ++i) pre[i] = pre[i - 1] + a[i]; g[1] = 0; for (int i = 1; i <= k; ++i) solve(i); i64 answer = limit; int v = 1 , ks = 1; for (int i = 1; i <= n; ++i) if (minimize(answer , g[i])) v = i - 1 , ks = i; cout << -g[ks] << '\n'; vector<int> recall; while (k > bug) { recall.emplace_back(v); v = trace[k][ks] - 1; ks = trace[k][ks]; --k; } reverse(recall.begin() , recall.end()); for (auto& v : recall) cout << v << ' '; }

Compilation message (stderr)

sequence.cpp: In member function 'std::pair<long long int, int> Convex_hull::find(i64)':
sequence.cpp:58:31: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   58 |                 int mid = low + high >> 1;
      |                           ~~~~^~~~~~
#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...