제출 #1337956

#제출 시각아이디문제언어결과실행 시간메모리
1337956alexddCollecting Stamps 4 (JOI25_stamps4)C++20
100 / 100
883 ms132568 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 2e18;
const int MAXV = 2e6 + 5;

struct AIB
{
    int v[MAXV];
    void init()
    {
        for(int i=0;i<MAXV;i++)
            v[i] = 0;
    }
    int qry(int poz)
    {
        int aux = 0;
        for(int i=poz;i>0;i-=(i&(-i)))
            aux += v[i];
        return aux;
    }
    void upd(int poz, int newv)
    {
        for(int i=poz;i<MAXV;i+=(i&(-i)))
            v[i] += newv;
    }
};

int n, x;
int a[MAXV], c[MAXV];

int base[MAXV];
void precalc()
{
    AIB ris, les;
    ris.init();
    les.init();

    base[1] = n * (n+1) / 2;
    vector<int> le(MAXV, 0), ri(MAXV, 0);
    for(int i=1;i<=2*n;i++)
    {
        if(!le[a[i]])
        {
            le[a[i]] = i;
            les.upd(i, +1);
        }
        else
        {
            ri[a[i]] = i;
            base[1] += ris.qry(i) - ris.qry(le[a[i]]);
            ris.upd(i, +1);
        }
    }

    for(int start=1;start<2*n;start++)
    {
        base[start + 1] = base[start];

        les.upd(le[a[start]], -1);
        ris.upd(ri[a[start]], -1);

        base[start + 1] -= les.qry(ri[a[start]]);
        base[start + 1] += ris.qry(start + 2*n) - ris.qry(ri[a[start]]);

        le[a[start]] = ri[a[start]];
        ri[a[start]] = start + 2*n;

        les.upd(le[a[start]], +1);
        ris.upd(ri[a[start]], +1);
    }
}

int sol[MAXV];

int minpref[MAXV], minsuff[MAXV];
signed main()
{

    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n>>x;
    for(int i=1;i<=2*n;i++)
    {
        cin>>a[i];
        a[2*n + i] = a[i];
    }
    for(int i=1;i<=2*n;i++)
    {
        cin>>c[i];
    }
    precalc();

    vector<pair<int,int>> qrys;
    int q;
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        int k;
        cin>>k;
        qrys.push_back({k, i});
        sol[i] = INF;
    }

    vector<pair<int,int>> bases;
    for(int i=1;i<=2*n;i++)
        bases.push_back({base[i], c[i]});
    sort(bases.begin(), bases.end());

    int mnm = INF;
    for(int i=0;i<bases.size();i++)
    {
        mnm = min(mnm, bases[i].second - x * bases[i].first);
        minpref[i] = mnm;
    }

    minsuff[bases.size()] = INF;
    for(int i = (int)bases.size() - 1; i >= 0; i--)
        minsuff[i] = min(minsuff[i+1], bases[i].second);

    sort(qrys.begin(), qrys.end());
    int poz = -1;
    for(auto [k,qid]:qrys)
    {
        while(poz + 1 < bases.size() && bases[poz + 1].first < k)
            poz++;
        if(poz != -1) sol[qid] = min(sol[qid], x*k + minpref[poz]);
        sol[qid] = min(sol[qid], minsuff[poz+1]);
    }

    for(int i=1;i<=q;i++)
    {
        assert(sol[i] != INF);
        cout<<sol[i]<<"\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...
#Verdict Execution timeMemoryGrader output
Fetching results...