제출 #1223061

#제출 시각아이디문제언어결과실행 시간메모리
1223061Szymon_Pilipczuk수열 (APIO14_sequence)C++20
0 / 100
0 ms320 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define int long long
#define st first
#define nd second
#define pb push_back
#define all(a) a.begin(),a.end()
#define rep(a,b) for(int a = 0;a<b;a++)
const int inf = 1e9;
const ll infl = 1e18;
int n,k;
ll sq(ll a)
{
    return a*a;
}
deque<vector<ll>> dq;
void add(ll a,ll b,int i)
{
    if(dq.size() == 0)
    {
        dq.push_back({0,infl,a,b,i});
        return;
    }
    vector<ll> c = dq.back();
    if(c[2] == a)
    {
        if(c[3] > b)
        {
            dq.pop_back();
            add(a,b,i);
        }
    }
    else
    {
        ll cu = (b-c[3])/(c[2]-a) + 1;
        if(cu <= c[0])
        {
            dq.pop_back();
            add(a,b,i);
        }
        else
        {
            dq.back()[1] = cu-1;
            dq.pb({cu,infl,a,b,i});
        }
    }
}
pair<ll,int> check(ll c)
{
    while(dq.front()[1] < c)
    {
        dq.pop_front();
    }
    return {c * dq.front()[2] + dq.front()[3],dq.front()[4]};
}
ll pref[100000];
int p[200][99999];
int32_t main()
{
    cin>>n>>k;
    int cv;
    cin>>cv;
    pref[0] = cv;  
    rep(i,n-1)
    {
        int c;
        cin>>c;
        pref[i+1] = pref[i]+c;
    }
    vector<vector<ll>> nx;
    vector<vector<ll>> nxnx;
    rep(q,k)
    {
        nx = nxnx;
        nxnx.clear();
        dq.clear();
        add(0,inf,-1);
        if(q == 0)
        {
            add(0,0,-1);
        }
        rep(i,n-1)
        {
            p[q][i] = check(pref[i]).nd;
            nxnx.pb({-2 * pref[i],check(pref[i]).st + sq(pref[i])*2,i});
            if(q != 0) add(nx[i][0],nx[i][1],nx[i][2]);
        }
    }
    dq.clear();
    rep(i,n-1)
    {
        add(nxnx[i][0],nxnx[i][1],nxnx[i][2]);
    }
    int ci = check(pref[n-1]).nd;
    int cu = k-1;
    vector<int> ord;
    while(ci != -1)
    {
        ord.pb(ci);
        ci = p[cu][ci];
        cu--;
    }
    reverse(all(ord));
    cout<<(check(pref[n-1]).st)/2<<"\n";
    rep(i,k)
    {
        cout<<ord[i]+1<<" ";
    }
    cout<<"\n";
}  
#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...