제출 #601442

#제출 시각아이디문제언어결과실행 시간메모리
601442Bench0310휴가 (IOI14_holiday)C++17
100 / 100
1197 ms15688 KiB
#include <bits/stdc++.h>
#include "holiday.h"

using namespace std;
typedef long long ll;

const int N=200005;
ll tree[4*N];
int cnt[4*N];

void update(int idx,int l,int r,int pos,ll dt,int dc)
{
    tree[idx]+=dt;
    cnt[idx]+=dc;
    if(l<r)
    {
        int m=(l+r)/2;
        if(pos<=m) update(2*idx,l,m,pos,dt,dc);
        else update(2*idx+1,m+1,r,pos,dt,dc);
    }
}

ll descend(int idx,int l,int r,int c)
{
    if(c>=cnt[idx]) return tree[idx];
    if(c<=0) return 0;
    int m=(l+r)/2;
    return descend(2*idx+1,m+1,r,c)+descend(2*idx,l,m,c-cnt[2*idx+1]);
}

vector<ll> eval(vector<int> a,int d)
{
    int n=(int)a.size()-1;
    vector<array<int,2>> h(n);
    for(int i=1;i<=n;i++) h[i-1]={a[i],i};
    sort(h.begin(),h.end());
    vector<int> pos(n+1,0);
    for(int i=0;i<n;i++) pos[h[i][1]]=i+1;
    vector<ll> dp(d+1,0);
    int idx=0;
    auto advance=[&](int nxt)
    {
        while(idx<nxt)
        {
            idx++;
            update(1,1,n,pos[idx],a[idx],1);
        }
        while(nxt<idx)
        {
            update(1,1,n,pos[idx],-a[idx],-1);
            idx--;
        }
    };
    queue<array<int,4>> q;
    q.push({0,d,0,n});
    while(!q.empty())
    {
        auto [l,r,ql,qr]=q.front();
        q.pop();
        //~ cout << "q [" << l << "," << r << "," << ql << "," << qr << "]" << endl;
        int m=(l+r)/2;
        array<ll,2> mx={0,0};
        for(int i=ql;i<=qr;i++)
        {
            advance(i);
            if(i<=m) mx=max(mx,{descend(1,1,n,m-i),-i});
        }
        dp[m]=mx[0];
        int qm=-mx[1];
        if(l<=m-1) q.push({l,m-1,ql,qm});
        if(m+1<=r) q.push({m+1,r,qm,qr});
    }
    advance(0);
    //~ cout << "solved [";
    //~ for(int i=1;i<=n;i++) cout << a[i] << ",]"[i==n];
    //~ cout << endl;
    //~ cout << "dp: ";
    //~ for(int i=0;i<=d;i++) cout << "[i=" << i << ": " << dp[i] << "] ";
    //~ cout << endl;
    return dp;
}

ll solve(int n,int s,int d,int attractions[])
{
    vector<int> one={0};
    for(int i=s+1;i<n;i++)
    {
        one.push_back(0);
        one.push_back(attractions[i]);
    }
    vector<int> two={0};
    for(int i=s-1;i>=0;i--) two.push_back(attractions[i]);
    vector<ll> r=eval(one,d);
    vector<ll> l=eval(two,d);
    ll res=0;
    for(int i=0;i<=d;i++)
    {
        res=max(res,l[i]+r[d-i]);
        if(i<d) res=max(res,l[i]+r[d-1-i]+attractions[s]);
    }
    return res;
}

ll findMaxAttraction(int n,int s,int d,int attractions[])
{
    ll res=solve(n,s,d,attractions);
    reverse(attractions,attractions+n);
    s=n-1-s;
    res=max(res,solve(n,s,d,attractions));
    return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...