제출 #538448

#제출 시각아이디문제언어결과실행 시간메모리
538448Lobo수열 (APIO14_sequence)C++17
100 / 100
1799 ms88180 KiB
#include<bits/stdc++.h> using namespace std; const long long inf = (long long) 1e13 + 10; const int inf1 = (int) 1e9 + 10; #define int long long #define ll long long #define dbl long double #define endl '\n' #define sc second #define fr first #define mp make_pair #define pb push_back #define all(x) x.begin(), x.end() #define maxn 100010 int n, k, a[maxn], ps[maxn]; int dp[maxn][2]; int32_t ant[maxn][202]; vector<pair<pair<int,int>,pair<pair<int,int>,int>>> cht; //cht -> a,b,l,r //chtlr -> l,r,a,b int f(int a, int b, int x) { return a*x + b; } dbl interx(int a1, int b1, int a2, int b2) { return (dbl) (b2-b1)/(a1-a2); } void resetcht() { cht.clear(); cht.pb(mp(mp(-inf1,+inf1),mp(mp(0,0),0))); } void attcht(int a, int b, int id) { // so vai tirar para a esquerda // vai tirando enquanto valer a pena int ansl = inf; while(cht.size()) { int a1 = cht.back().sc.fr.fr; int b1 = cht.back().sc.fr.sc; int l = cht.back().fr.fr; int r = cht.back().fr.sc; int id1 = cht.back().sc.sc; if(f(a,b,l) >= f(a1,b1,l)) { cht.pop_back(); ansl = l; } else if(f(a,b,r) >= f(a1,b1,r)) { int x = ceil(interx(a,b,a1,b1)); cht.pop_back(); cht.pb(mp(mp(l,x-1),mp(mp(a1,b1),id1))); ansl = x; break; } else { break; } } if(ansl <= inf1) { cht.pb(mp(mp(ansl,inf1),mp(mp(a,b),id))); } } int idq; pair<int,int> qrr(int x) { idq = min(idq,(int) cht.size()-1); while(idq+1 != cht.size()) { int a = cht[idq].sc.fr.fr; int b = cht[idq].sc.fr.sc; int a1 = cht[idq+1].sc.fr.fr; int b1 = cht[idq+1].sc.fr.sc; if(f(a1,b1,x) >= f(a,b,x)) idq++; else break; } int a = cht[idq].sc.fr.fr; int b = cht[idq].sc.fr.sc; return mp(f(a,b,x),cht[idq].sc.sc); } void solve() { cin >> n >> k; for(int i = 1; i <= n; i++) { cin >> a[i]; ps[i] = ps[i-1] + a[i]; } for(int j = 1; j <= k; j++) { resetcht(); //dp[0][j] = 0 idq = 0; for(int i = j; i <= n; i++) { auto qr = qrr(ps[i]); dp[i][j&1] = qr.fr; ant[i][j] = qr.sc; attcht(ps[i],dp[i][j&1^1]-ps[i]*ps[i],i); } } //dp[i][k] = max(dp[j-1][k-1] + ps[j-1]*(ps[i]-ps[j-1])) //dp[j-1][k-1] - ps[j-1]² + ps[j-1]*ps[i] //a ordem que vai colocando é crescente entao é só usar um vector bem mais simples int id = n; vector<int> ans; for(int j = k; j >= 1; j--) { ans.pb(ant[id][j]); id = ant[id][j]; } reverse(all(ans)); cout << dp[n][k&1] << endl; for(auto x : ans) cout << x << " "; cout << endl; } int32_t main() { ios::sync_with_stdio(false); cin.tie(0); // freopen("in.in", "r", stdin); // freopen("out.out", "w", stdout); int tt = 1; // cin >> tt; while(tt--) solve(); }

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

sequence.cpp: In function 'std::pair<long long int, long long int> qrr(long long int)':
sequence.cpp:77:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<std::pair<long long int, long long int>, std::pair<std::pair<long long int, long long int>, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |     while(idq+1 != cht.size()) {
      |           ~~~~~~^~~~~~~~~~~~~
sequence.cpp: In function 'void solve()':
sequence.cpp:107:33: warning: suggest parentheses around arithmetic in operand of '^' [-Wparentheses]
  107 |             attcht(ps[i],dp[i][j&1^1]-ps[i]*ps[i],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...