Submission #627805

#TimeUsernameProblemLanguageResultExecution timeMemory
627805ETKRarest Insects (IOI22_insects)C++17
100 / 100
59 ms420 KiB
#include <bits/stdc++.h>
#include "insects.h"
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define pb push_back
#define ALL(x) x.begin(),x.end()
#define sz(x) int(x.size())
#define ll long long
using namespace std;
const int N = 2e5 + 5;
//int n,a[N],b[N];
// void move_inside(int i){
//     ++b[a[i]];
// }
// void move_outside(int i){
//     --b[a[i]];
// }
// int press_button(){
//     int mx = 0;
//     rep(i,1,n)mx = max(mx,b[i]);
//     return mx;
// }
int min_cardinality(int n){
    mt19937 mt(19260817);
    int cnt = 0;
    vi vis(n,0);
    rep(i,0,n - 1){
        move_inside(i);
        //appeared before
        if(i && press_button() > 1)move_outside(i);
        else vis[i] = 1,cnt++;
    }
    int tmp = cnt,L = 2,R = n / cnt,ans = 1;
    vi rem,p(n);
    iota(ALL(p),0);
    while(L <= R){
        int k = (L + R) >> 1;
        shuffle(ALL(p),mt);
        rep(t,0,n - 1){
            int i = p[t];
            if(vis[i])continue;
            move_inside(i);
            if(press_button() > k){
                move_outside(i);
                rem.pb(i);
            }
            else tmp++;
            if(tmp == k * cnt){//all kind are in the bucket
                rep(j,t + 1,n - 1)if(!vis[p[j]]){
                    rem.pb(p[j]);
                }
              //stop the meaningless process
                break;
            }
        }
        if(k * cnt == tmp){
            ans = k,L = k + 1;
            //if greater than k, you don't need to throw away the insects in your bucket.
            //You only need to consider the insects left.
            rep(i,0,n - 1)vis[i] = 1;
            for(int x : rem)vis[x] = 0;
        }else{
            R = k - 1;
            //if the answer is smaller than k,you won't need the (k+1)th insects
            for(int x : rem)vis[x] = 1;
            rep(i,0,n - 1)if(!vis[i]){
                move_outside(i);
                tmp--;
            }
        }
        rem.clear();
    }
    return ans;
}
// int main(){
//     cin >> n;
//     rep(i,0,n - 1)cin >> a[i];
//     cout << min_cardinality(n) << '\n';
// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...