Submission #573462

# Submission time Handle Problem Language Result Execution time Memory
573462 2022-06-06T16:30:36 Z perchuts Holiday (IOI14_holiday) C++17
100 / 100
436 ms 7184 KB
#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define endl '\n'
#define pb push_back
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include "holiday.h"

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ii = pair<int,int>;
using iii = tuple<int,int,int>;

const int inf = 2e9+1;
const int mod = 1e9+7;
const int maxn = 1e5+100;

template<typename X, typename Y> bool ckmin(X& x, const Y& y) { return (y < x) ? (x=y,1):0; }
template<typename X, typename Y> bool ckmax(X& x, const Y& y) { return (x < y) ? (x=y,1):0; }
//dp[i][j]: visito as cidades [i,j] (i<=start<=j). vamos gastar j-i + j-start dias andando
//logo, queremos a soma dos max(0,min(d - (2j - start - i),j-i+1)) maiores numeros entre [i,j]. 
//igualzinho o cake3, mas nao da pra usar persistencia nesse por causa da memoria...
//preciso achar os m maiores numeros entre [i,j] em log

pair<ll,int> seg[4*maxn];
ll v[maxn];
vector<int>ord;
int n, _ord[maxn];

void build(int i,int l,int r){
    if(l==r){
        seg[i] = {v[ord[l]],1};
        return;
    } 
    int md = (l+r)/2;
    build(2*i,l,md), build(2*i+1,md+1,r);
    seg[i].first = seg[2*i].first + seg[2*i+1].first;
    seg[i].second = seg[2*i].second + seg[2*i+1].second;
}

int curL, curR, st;
ll ans = 0;

void update(int i,int l,int r,int x,bool type){
    if(l>x||r<x)return;
    if(l==r){
        seg[i] = (type?make_pair(v[ord[l]],1):make_pair(0ll,0));
        return;
    }
    int md = (l+r)/2;
    update(2*i,l,md,x,type), update(2*i+1,md+1,r,x,type);
    seg[i].first = seg[2*i].first + seg[2*i+1].first;
    seg[i].second = seg[2*i].second + seg[2*i+1].second;
}

ll query(int i,int l,int r,int qnt){
    if(l==r)return qnt?seg[i].first:0;
    int md = (l+r)/2;
    if(seg[2*i+1].second>=qnt)return query(2*i+1,md+1,r,qnt);
    return seg[2*i+1].first + query(2*i,l,md,qnt-seg[2*i+1].second);
}

ll query(int l,int r,int d){
    while(curL<l)update(1,1,n,_ord[curL],0),curL++;
    while(curL>l)curL--,update(1,1,n,_ord[curL],1);
    while(curR<r)curR++,update(1,1,n,_ord[curR],1);
    while(curR>r)update(1,1,n,_ord[curR],0),curR--;
    return query(1,1,n,d);
}

void compute(int l,int r,int lx,int rx,int d){
    if(l>r)return;
    int md = (l+r)/2;
    ll best = -1, opt = -1;
    for(int i=lx;i<=min(md,rx);++i){
        ll cur = query(i,md, max(0,max(d - (2*md - st - i),d - (md + st - 2*i))));
        if(ckmax(best,cur))opt = i;
    }
    assert(opt!=-1);
    ckmax(ans,best);
    compute(l,md-1,lx,opt,d), compute(md+1,r,opt,rx,d);
}

ll findMaxAttraction(int N, int start, int d, int attraction[]) {
    ++start, n = N;

    for(int i=0;i<n;++i)v[i+1] = ll(attraction[i]);
    v[0] = -1; 
    ord.resize(n+1),iota(all(ord),0),sort(all(ord), [&](int x,int y){
        return v[x] < v[y];
    });    

    for(int i=1;i<=n;++i)_ord[ord[i]] = i;

    build(1,1,n);
    curL = 1, curR = n, st = start;

    compute(st,n,1,st,d);

    return ans;
}

// int attraction[maxn];

// int main(){
//     int n, start, d;cin>>n>>start>>d;
//     for(int i=0;i<n;++i)cin>>attraction[i];
//     cout<<findMaxAttraction(n,start,d,attraction)<<endl;
// }
# Verdict Execution time Memory Grader output
1 Correct 1 ms 596 KB Output is correct
2 Correct 1 ms 712 KB Output is correct
3 Correct 1 ms 596 KB Output is correct
4 Correct 1 ms 596 KB Output is correct
5 Correct 1 ms 596 KB Output is correct
6 Correct 1 ms 712 KB Output is correct
7 Correct 1 ms 596 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 135 ms 6484 KB Output is correct
2 Correct 137 ms 6560 KB Output is correct
3 Correct 143 ms 6564 KB Output is correct
4 Correct 138 ms 6564 KB Output is correct
5 Correct 161 ms 6428 KB Output is correct
6 Correct 42 ms 2132 KB Output is correct
7 Correct 82 ms 3700 KB Output is correct
8 Correct 104 ms 3908 KB Output is correct
9 Correct 27 ms 2084 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 852 KB Output is correct
2 Correct 2 ms 852 KB Output is correct
3 Correct 2 ms 852 KB Output is correct
4 Correct 5 ms 852 KB Output is correct
5 Correct 7 ms 852 KB Output is correct
6 Correct 2 ms 724 KB Output is correct
7 Correct 2 ms 704 KB Output is correct
8 Correct 2 ms 712 KB Output is correct
9 Correct 2 ms 724 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 43 ms 6620 KB Output is correct
2 Correct 148 ms 6620 KB Output is correct
3 Correct 205 ms 3792 KB Output is correct
4 Correct 7 ms 852 KB Output is correct
5 Correct 2 ms 724 KB Output is correct
6 Correct 3 ms 704 KB Output is correct
7 Correct 2 ms 724 KB Output is correct
8 Correct 436 ms 7108 KB Output is correct
9 Correct 418 ms 7184 KB Output is correct