제출 #1057260

#제출 시각아이디문제언어결과실행 시간메모리
1057260Zbyszek99The short shank; Redemption (BOI21_prison)C++17
0 / 100
54 ms114728 KiB
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define size(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace std;
//mt19937 mt;void random(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll rand(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;

const int MAXN = 2000010;
const int wiel_tree = 1024*4096-1;

pii drzewo[wiel_tree];
int oper[wiel_tree]; 
int n,d,t;
int pre[MAXN];
int max_pre[MAXN];
vector<int> graf[MAXN];
int arr[MAXN];
int parent[MAXN];
int cur_pre;
int depth[MAXN];
bool was_take[MAXN];

void add_pom(int akt, int p1, int p2, int s1, int s2)
{
    if(akt != 1) drzewo[akt-1].ff += oper[akt/2-1];
    if(akt != 1) oper[akt-1] += oper[akt/2-1];
    if(p2 < s1 || p1 > s2) return;
    if(p1 >= s1 && p2 <= s2)
    {
        drzewo[akt-1].ff--;
        oper[akt-1]--;
        return;
    }
    add_pom(akt*2,p1,(p1+p2)/2,s1,s2);
    add_pom(akt*2+1,(p1+p2)/2+1,p2,s1,s2);
    drzewo[akt-1] = max(drzewo[akt*2-1],drzewo[akt*2]);
    oper[akt-1] = 0;
}

pii get_max()
{
    return drzewo[0];
}

void dfs(int v, int dep = 1)
{
    depth[v] = dep;
    dep++;
    pre[v] = cur_pre++;
    max_pre[v] = pre[v];
    forall(it,graf[v])
    {
        dfs(it,dep);
        max_pre[v] = max_pre[it];
    }
}

void solve()
{
    cin >> n >> d >> t;
    rep(i,n) cin >> arr[i];
    stack<int> st;
    rep(i,n) parent[i] = -1;
    for(int i = n-1; i >= 0; i--)
    {
        if(arr[i] > t && size(st) > 0)
        {
            graf[st.top()].pb(i);
            parent[i] = st.top();
        }
        st.push(i);
        while(size(st) > 0 && i + t - arr[i] >= st.top())
        {
            st.pop();
        }
    }
    rep(i,n)
    {
        if(parent[i] == -1)
        {
            dfs(i);
        }
    }
    rep(i,n)
    {
        drzewo[wiel_tree/2+pre[i]] = {depth[i],i};
    }
    rep2(i,wiel_tree/2+n,wiel_tree-1) drzewo[i] = {0,0};
    for(int i = wiel_tree/2-1; i >= 0; i--)
    {
        drzewo[i] = max(drzewo[i*2+1],drzewo[i*2+2]);
    }
    int ans = n;
    rep(i,d)
    {
        pii m = get_max();
        if(m.ff == 0) break;
        ans -= m.ff;
        int v = m.ss;
        while(v != -1 && !was_take[v])
        {
            was_take[v] = true;
            add_pom(1,0,wiel_tree/2,pre[v],max_pre[v]);
            v = parent[v];
        }
    }
    cout << ans;
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //random();
    int t = 1;
    //cin >> t;
    while(t--) solve();
}
#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...