Submission #815259

#TimeUsernameProblemLanguageResultExecution timeMemory
815259JakobZorzRarest Insects (IOI22_insects)C++17
63.09 / 100
131 ms628 KiB
#include"insects.h"
#include<iostream>
#include<vector>
#include<set>
using namespace std;

vector<bool>inside;
vector<bool>configs[2000];
int sizes[2000];
int num_inside;
int n,distinct;
int low_bound,high_bound;

int c_press_button(){
    return press_button();
}

void c_move_inside(int a){
    inside[a]=true;
    num_inside++;
    move_inside(a);
}

void c_move_outside(int a){
    inside[a]=false;
    num_inside--;
    move_outside(a);
}

void check(int c){
    int nearest_i=c;
    while(configs[nearest_i].empty())
        nearest_i--;
    
    vector<bool>nearest_config=configs[nearest_i];
    for(int i=0;i<n;i++){
        if(nearest_config[i]!=inside[i]){
            if(inside[i])
                c_move_outside(i);
            else
                c_move_inside(i);
        }
    }
    
    int button_ub=nearest_i;
    
    for(int i=0;i<n;i++){
        if(!inside[i]){
            c_move_inside(i);
            button_ub++;
            if(button_ub>c)
                button_ub=c_press_button();
            
            if(sizes[button_ub]<num_inside){
                sizes[button_ub]=num_inside;
                configs[button_ub]=inside;
            }
            
            if(button_ub>c)
                c_move_outside(i);
        }
    }
    
    configs[c]=inside;
    
    bool res=num_inside==c*distinct;
    
    if(res){
        low_bound=max(low_bound,c);
        high_bound=min(high_bound,c+(n-c*distinct)/distinct+1);
    }else{
        low_bound=max(low_bound,c-(c*distinct-num_inside));
        high_bound=min(high_bound,c);
    }
}

int get_distinct(){
    for(int i=0;i<n;i++){
        c_move_inside(i);
        if(c_press_button()>1)
            c_move_outside(i);
    }
    
    configs[1]=inside;
    sizes[1]=num_inside;
    
    return num_inside;
}

int min_cardinality(int N){
    n=N;
    inside.resize(n);
    distinct=get_distinct();
    if(distinct>n/2)
        return 1;
    if(distinct==1)
        return n;
    low_bound=1;
    high_bound=n/distinct+1;
    
    while(low_bound<high_bound-1){
        int w1=2;
        int w2=1;
        
        int m=(w1*low_bound+w2*high_bound+w1+w2-1)/(w1+w2);
        check(m);
    }
    return low_bound;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...