답안 #770638

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
770638 2023-07-01T14:52:32 Z adrilen 코끼리 (Dancing Elephants) (IOI11_elephants) C++17
100 / 100
4260 ms 12444 KB
#include "elephants.h"
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using arr = array<int, 2>;
using arrr = array<int, 3>;

// Start = 100
constexpr int maxn = 1.5e5, start_size = 100, num_groups = maxn / start_size + 1;

int n, l;

struct Group {
    int n;
    vector <int> pos;
    vector <arr> pref;

    void calc()             // O(n log n)
    {
        assert(n == (int)pos.size());
        pref.resize(n + 1);

        pref[n] = {0, 0};
        sort(pos.begin(), pos.end());

        for (int p = n - 1; p >= 0; p--)
        {
            int ind = upper_bound(pos.begin(), pos.end(), pos[p] + l) - pos.begin();    
            
            pref[p] = {pref[ind][0] + 1, max(pos[p] + l, pref[ind][1])};
        }
    }

    void insert(int p, bool up = false)     // O(sqrt(n))
    {
        pos.emplace_back(p);
        n++;
        if (up) calc();
    }

    void erase(int p, bool up = false)      // O(sqrt(n))
    {
        n--;
        pos.erase(lower_bound(pos.begin(), pos.end(), p));

        if (up) calc();
    }

} ;

vector<Group> groups;


void split_group(int p)
{   
    Group ne = Group();

    ne.pos = vector<int>(groups[p].pos.begin() + groups[p].n / 2, groups[p].pos.end());

    // cout <<"aa\n";
    // for (int i : ne.pos) cout << i << " ";
    // cout << "\n";
    groups[p].pos.resize(groups[p].n / 2);
    groups[p].n /= 2;

    groups[p].calc();

    ne.n = ne.pos.size();
    ne.calc();

    groups.insert(groups.begin() + p + 1, ne);
}


void print_groups()
{
    for (int a = 0; a < (int)groups.size(); a++)
    {
        cout << a << " " << groups[a].n << " " << groups[a].pos.size() <<  "\n";
        for (int i : groups[a].pos) cout << i << "\t";
        cout << "\n";
        for (arr i : groups[a].pref) cout << i[0] << " " << i[1] << "\t";
        cout << "\n";

    }
    cout << endl;
}


int get_total()                         // O(n / sqrt(n) log n)
{
    int output = 0;

    int last_length = -1;
    for (int i = 0; i < (int)groups.size(); i++)
    {
        int pos = upper_bound(groups[i].pos.begin(), groups[i].pos.end(), last_length) - groups[i].pos.begin();

        output += groups[i].pref[pos][0];
        last_length = max(last_length, groups[i].pref[pos][1]);
    }

    return output;
}


int ind_to_pos[maxn] = { 0 };
void init(int N, int L, int X[])            // O(n / sqrt(n))
{
    n = N, l = L;
    
    for (int i = 0; i < n; i++) ind_to_pos[i] = X[i];


    groups.resize((n - 1) / start_size + 1);

    for (int y = 0; y <= n / start_size; y++)
    {
        for (int i = 0; i < start_size; i++)
        {
            if (y * start_size + i == n) {
                y = 2e9;
                break;
            }
            groups[y].insert(X[y * start_size + i]);
        }
    }
    // print_groups();

    int y;
    for (y = 0; y < (int)groups.size(); y++)
    {
        groups[y].calc();
    }
    assert((int)groups.size() == y);

    // print_groups();
}





int fnd_group(int p)
{
    int l = 0, r = groups.size() - 1, mid;

    while (l != r)
    {
        mid = (l + r) >> 1;

        if (groups[mid].pos.back() < p) l = mid + 1;
        else r = mid;
    }

    return l;
}

int q = 0;
int update(const int i, int y)
{
    // cout << "NEW QUERY\n";

    int u = ind_to_pos[i]; // Now position

    int j = fnd_group(u);

    groups[j].erase(u, true);

    if (groups[j].n == 0)
    {
        groups.erase(groups.begin() + j);
    }

    ind_to_pos[i] = y;

    j = fnd_group(y);
    groups[j].insert(y, true);


    if (groups[j].n >= start_size * 1.5) split_group(j);

    // print_groups();

    // q++;
    // if (q % 1000 == 0)
    // {
    //     for (int x = 0; x < groups.size(); x++)
    //     {
    //         cout << groups[x].n << " ";
    //     }
    //     cout << "\n";
    // }

    return get_total();
}


/*
g++ -o $PROBLEM grader.cpp $PROBLEM.cpp -fsanitize="address","undefined" -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -Wall -g3 -O2 && ./$PROBLEM
g++ -o $PROBLEM grader.cpp $PROBLEM.cpp -Wall -g3 && ./$PROBLEM


*/
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 0 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 0 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 0 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 0 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 0 ms 340 KB Output is correct
7 Correct 341 ms 1228 KB Output is correct
8 Correct 415 ms 2364 KB Output is correct
9 Correct 421 ms 3744 KB Output is correct
10 Correct 370 ms 3868 KB Output is correct
11 Correct 366 ms 3828 KB Output is correct
12 Correct 582 ms 3888 KB Output is correct
13 Correct 395 ms 3692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 0 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 0 ms 340 KB Output is correct
7 Correct 341 ms 1228 KB Output is correct
8 Correct 415 ms 2364 KB Output is correct
9 Correct 421 ms 3744 KB Output is correct
10 Correct 370 ms 3868 KB Output is correct
11 Correct 366 ms 3828 KB Output is correct
12 Correct 582 ms 3888 KB Output is correct
13 Correct 395 ms 3692 KB Output is correct
14 Correct 322 ms 3300 KB Output is correct
15 Correct 503 ms 3252 KB Output is correct
16 Correct 819 ms 4468 KB Output is correct
17 Correct 991 ms 5516 KB Output is correct
18 Correct 1067 ms 5036 KB Output is correct
19 Correct 765 ms 5064 KB Output is correct
20 Correct 1055 ms 5632 KB Output is correct
21 Correct 1051 ms 5236 KB Output is correct
22 Correct 728 ms 5036 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 0 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 0 ms 340 KB Output is correct
7 Correct 341 ms 1228 KB Output is correct
8 Correct 415 ms 2364 KB Output is correct
9 Correct 421 ms 3744 KB Output is correct
10 Correct 370 ms 3868 KB Output is correct
11 Correct 366 ms 3828 KB Output is correct
12 Correct 582 ms 3888 KB Output is correct
13 Correct 395 ms 3692 KB Output is correct
14 Correct 322 ms 3300 KB Output is correct
15 Correct 503 ms 3252 KB Output is correct
16 Correct 819 ms 4468 KB Output is correct
17 Correct 991 ms 5516 KB Output is correct
18 Correct 1067 ms 5036 KB Output is correct
19 Correct 765 ms 5064 KB Output is correct
20 Correct 1055 ms 5632 KB Output is correct
21 Correct 1051 ms 5236 KB Output is correct
22 Correct 728 ms 5036 KB Output is correct
23 Correct 3688 ms 11288 KB Output is correct
24 Correct 4035 ms 11204 KB Output is correct
25 Correct 3221 ms 10876 KB Output is correct
26 Correct 3684 ms 12012 KB Output is correct
27 Correct 4030 ms 10724 KB Output is correct
28 Correct 647 ms 5164 KB Output is correct
29 Correct 605 ms 5340 KB Output is correct
30 Correct 694 ms 5324 KB Output is correct
31 Correct 581 ms 5128 KB Output is correct
32 Correct 3028 ms 11444 KB Output is correct
33 Correct 3030 ms 10772 KB Output is correct
34 Correct 2997 ms 11776 KB Output is correct
35 Correct 3190 ms 10508 KB Output is correct
36 Correct 2506 ms 9752 KB Output is correct
37 Correct 4154 ms 12444 KB Output is correct
38 Correct 2847 ms 10660 KB Output is correct
39 Correct 2981 ms 10528 KB Output is correct
40 Correct 3122 ms 10684 KB Output is correct
41 Correct 4260 ms 11408 KB Output is correct
42 Correct 4212 ms 11468 KB Output is correct