Submission #782036

#TimeUsernameProblemLanguageResultExecution timeMemory
782036TheSahib커다란 상품 (IOI17_prize)C++14
20 / 100
67 ms28988 KiB
#include "prize.h"
#include <bits/stdc++.h>

using namespace std;

const int MAX = 2e5 + 5;
const int BLOCK = 400;

int tree[MAX];

void update(int pos, int val){
    while(pos < MAX){
        tree[pos] += val;
        pos += pos & (-pos);
    }
}

int ask(int l, int r){
    if(r < l) return 0;
    if(l != 1) return ask(1, r) - ask(1, l - 1);
    int ans = 0;
    while(r > 0){
        ans += tree[r];
        r -= r & (-r);
    }
    return ans;
}

int intRand(){
    return (rand() << 14) | rand();
}

vector<int> mp[MAX];

vector<int> query(int i){
    if(!mp[i].empty()) return mp[i];
    return mp[i] = ask(i - 1);
}


int find_best(int n) {
    vector<int> order(n);
    srand(time(0));
    iota(order.begin(), order.end(), 1);
    random_shuffle(order.begin(), order.end());
    vector<int> a;
    int cnt = 0;
    
    set<int> st;
    for (int i = 0; i < n; i++)
    {
        st.insert(i + 1);
    }
    for (int j = 0; j < min(500, (int)order.size()); ++j)
    {
        int i = order[j];
        a = query(i);
        if(a[0] + a[1] == 0) return i - 1;
        if(a[0] + a[1] < cnt){
            update(i, 1);
            st.erase(i);
        }
        else{
            cnt = a[0] + a[1];
        }
    }
    
    vector<int> blocks = {1, n};
    int c = 0;
    
    
    for (int i = 0; i < blocks.size() - 1; i++)
    {
        int b1 = blocks[i], b2 = blocks[i + 1];
        int d = query(b1)[2] - query(b2)[2] - ask(b1, b2);
        for(int i = 0; i < d; ++i);
        {
            int l = b1, r = b2;
            while(l <= r){
                int x = (l + r) / 2;
                auto itr = st.lower_bound(x);
                if(itr == st.end() || (*itr) > r){
                    --itr;
                }
                int mid = *itr;
                a = query(mid);
    
                if(a[0] + a[1] == 0){
                    return mid - 1;
                }
                if(a[0] + a[1] < cnt){
                    update(mid, 1);
                    st.erase(mid);
                    break;
                }
                a[0] -= query(b1)[0];
                a[0] -= ask(b1, mid - 1);
                a[1] -= query(b2)[1];
                a[1] -= ask(mid + 1, b2);
    
    
                if(a[1] > 0){
                    l = mid + 1;
                }
                else{
                    r = mid - 1;
                }
            }
        }
    }
    
}

Compilation message (stderr)

prize.cpp: In function 'int find_best(int)':
prize.cpp:72:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   72 |     for (int i = 0; i < blocks.size() - 1; i++)
      |                     ~~^~~~~~~~~~~~~~~~~~~
prize.cpp:76:9: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   76 |         for(int i = 0; i < d; ++i);
      |         ^~~
prize.cpp:77:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   77 |         {
      |         ^
prize.cpp:69:9: warning: unused variable 'c' [-Wunused-variable]
   69 |     int c = 0;
      |         ^
prize.cpp:42:24: warning: control reaches end of non-void function [-Wreturn-type]
   42 |     vector<int> order(n);
      |                        ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...