제출 #1333401

#제출 시각아이디문제언어결과실행 시간메모리
1333401Aviansh휴가 (IOI14_holiday)C++20
0 / 100
56 ms131072 KiB
#include"holiday.h"
#include <bits/stdc++.h>

using namespace std;

#define int long long

struct perSegTree{
    struct node{
        int active;
        int sum;
        int l,r;
    };
    node *st;
    int cr=0;
    node def;
    void makeKids(int ind, int l, int r){
        if(l==r)
            return;
        if(st[ind].l==-1){
            st[ind].l=++cr;
            st[ind].r=++cr;
        }
    }
    int cop(int ind){
        st[++cr]=st[ind];
        return cr;
    }
    perSegTree(int nodes){
        st=new node[nodes];
        def={0,0,-1,-1};
        fill(st,st+nodes,def);
    }
    int update(int l, int r, int i, int val, int ind){
        if(i<l||i>r)
            return ind;
        makeKids(ind,l,r);
        ind = cop(ind);
        if(l==r){
            st[ind].active=1;
            st[ind].sum=val;
            return ind;
        }
        int mid = (l+r)/2;
        st[ind].l=update(l,mid,i,val,st[ind].l);
        st[ind].r=update(mid+1,r,i,val,st[ind].r);
        st[ind].active=st[st[ind].l].active+st[st[ind].r].active;
        st[ind].sum=st[st[ind].l].sum+st[st[ind].r].sum;
        return ind;
    }
    array<int,2>query(int l, int r, int s, int e, int ind){
        if(e<l||s>r)
            return {0,0};
        if(s<=l&&r<=e){
            return {st[ind].active,st[ind].sum};
        }
        int mid = (l+r)/2;
        array<int,2>lef = query(l,mid,s,e,st[ind].l);
        array<int,2>rig = query(mid+1,r,s,e,st[ind].r);
        return {lef[0]+rig[0],lef[1]+rig[1]};
    }
};

int ans;

void findAns(int ll, int lr, int rl, int rr, perSegTree &seg, int d, int st, int inds[], int n){
    if(lr<ll)
        return;
    int k = (ll+lr)/2;
    int optval = 0;
    int opt = -1;
    for(int i = rl;i<=rr;i++){
        int lef = 2*(st-k)+(i-st);
        lef=d-lef;
        if(lef<=0){
            break;
        }
        int lo = 0;
        int hi = n;
        while(lo<hi){
            int mid = (lo+hi)/2;
            if(seg.query(0,n-1,k,i,inds[mid])[0]<lef){
                lo=mid+1;
            }
            else{
                hi=mid;
            }
        }
        if(optval<seg.query(0,n-1,k,i,inds[lo])[1]){
            optval=seg.query(0,n-1,k,i,inds[lo])[1];
            opt=i;
        }
    }
    if(opt==-1){
        //impossible for this one
        findAns(k+1,lr,rl,rr,seg,d,st,inds,n);
        return;
    }
    ans=max(ans,optval);
    if(ll!=lr){
        findAns(ll,k-1,rl,opt,seg,d,st,inds,n);
        findAns(k+1,lr,opt,rr,seg,d,st,inds,n);
    }
}

void justLeft(perSegTree &seg, int start, int n, int d, int inds[]){
    for(int i = 0;i<=start;i++){
        int l = start-i+1;
        if(l>d)
            continue;
        int lo = 0;
        int hi = n;
        while(lo<hi){
            int mid = (lo+hi)/2;
            if(seg.query(0,n-1,i,start,inds[mid])[0]<(d-l)){
                lo=mid+1;
            }
            else{
                hi=mid;
            }
        }
        ans=max(ans,seg.query(0,n-1,i,start,inds[lo])[1]);
    }
}

long long findMaxAttraction(signed n, signed start, signed d, signed attraction[]) {
    ans=0;
    perSegTree seg(1e8);
    array<int,2>arr[n];
    for(int i = 0;i<n;i++){
        arr[i]={attraction[i],i};
    }
    sort(arr,arr+n);
    reverse(arr,arr+n);
    int inds[n+1];
    inds[0]=0;
    for(int i = 0;i<n;i++){
        inds[i+1]=seg.update(0,n-1,arr[i][1],arr[i][0],inds[i]);
    }
    justLeft(seg,start,n,d, inds);
    findAns(0,start,start,n-1,seg,d,start,inds,n);
    reverse(attraction,attraction+n);
    start=n-start-1;
    seg = perSegTree(1e8);
    for(int i = 0;i<n;i++){
        arr[i]={attraction[i],i};
    }
    sort(arr,arr+n);
    reverse(arr,arr+n);
    inds[0]=0;
    for(int i = 0;i<n;i++){
        inds[i+1]=seg.update(0,n-1,arr[i][1],arr[i][0],inds[i]);
    }
    justLeft(seg,start,n,d, inds);
    findAns(0,start,start,n-1,seg,d,start,inds,n);
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...