답안 #622594

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
622594 2022-08-04T12:05:34 Z wiwiho 식물 비교 (IOI20_plants) C++14
100 / 100
1749 ms 85024 KB
#include "plants.h"

#include <bits/stdc++.h>

#define iter(a) a.begin(), a.end()
#define lsort(a) sort(iter(a))
#define gsort(a) sort(iter(a), greater<>())
#define eb emplace_back
#define ef emplace_front
#define pob pop_back()
#define pof pop_front()
#define mp make_pair
#define F first
#define S second
#define uni(a) a.resize(unique(iter(a)) - a.begin())
#define printv(a, b) { \
    for(auto pv : a) b << pv << " "; \
    b << "\n"; \
}

using namespace std;

typedef long long ll;

using pii = pair<int, int>;
using pll = pair<ll, ll>;

const ll MAX = 1e6;

template<typename A, typename B>
ostream& operator<<(ostream& o, pair<A, B> p){
    return o << '(' << p.F << ',' << p.S << ')';
}

void waassert(bool t){
    if(t) return;
    exit(0);
}

int n, K;
vector<int> rec;
vector<bool> use;

struct Node{
    int mn = 0, pos = 0, tag = 0;
};

Node operator+(Node a, Node b){
    Node c;
    c.mn = min(a.mn, b.mn);
    if(a.mn == c.mn) c.pos = a.pos;
    else c.pos = b.pos;
    return c;
}

vector<Node> st;
#define lc 2 * id + 1
#define rc 2 * id + 2

void build(vector<int>& o, int L = 0, int R = n - 1, int id = 0){
    if(L == R){
        st[id].mn = o[L];
        st[id].pos = L;
        return;
    }
    int M = (L + R) / 2;
    build(o, L, M, lc);
    build(o, M + 1, R, rc);
    st[id] = st[lc] + st[rc];
}

void addtag(int v, int id){
    st[id].tag += v;
    st[id].mn += v;
}

void push(int id){
    addtag(st[id].tag, lc);
    addtag(st[id].tag, rc);
    st[id].tag = 0;
}

void _modify(int l, int r, int v, int L = 0, int R = n - 1, int id = 0){
    if(l <= L && R <= r){
        addtag(v, id);
        return;
    }
    push(id);
    int M = (L + R) / 2;
    if(r <= M) _modify(l, r, v, L, M, lc);
    else if(l > M) _modify(l, r, v, M + 1, R, rc);
    else{
        _modify(l, r, v, L, M, lc);
        _modify(l, r, v, M + 1, R, rc);
    }
    st[id] = st[lc] + st[rc];
}

void modify(int l, int r, int v){
    l = (l % n + n) % n;
    r = (r % n + n) % n;
    if(l <= r) _modify(l, r, v);
    else{
        _modify(l, n - 1, v);
        _modify(0, r, v);
    }
}

Node _query(int l, int r, int L = 0, int R = n - 1, int id = 0){
    if(l <= L && R <= r) return st[id];
    push(id);
    int M = (L + R) / 2;
    if(r <= M) return _query(l, r, L, M, lc);
    else if(l > M) return _query(l, r, M + 1, R, rc);
    else return _query(l, r, L, M, lc) + _query(l, r, M + 1, R, rc);
}

Node query(int l, int r){
    l = (l % n + n) % n;
    r = (r % n + n) % n;
    if(l <= r) return _query(l, r);
    else{
        return _query(l, n - 1) + _query(0, r);
    }
}

void _print(int L = 0, int R = n - 1, int id = 0){
    if(L == R){
        cerr << st[id].mn << " ";
        return;
    }
    push(id);
    int M = (L + R) / 2;
    _print(L, M, lc);
    _print(M + 1, R, rc);
}

void print(){
    _print();
    cerr << "\n";
}

int getdis(int l, int r){
    l = (l % n + n) % n;
    r = (r % n + n) % n;
    if(l == r) return n;
    if(l > r) r += n;
    return r - l;
}

set<int> zero;
set<pii> sep;
vector<int> rk;

void solve(int _rk){
    
    while(st[0].mn == 0){
        int pos = st[0].pos;
        modify(pos, pos, MAX);

        if(zero.empty()){
            zero.insert(pos);
            sep.insert(mp(n, pos));
            continue;
        }
        
        auto it = zero.lower_bound(pos);
        if(it == zero.end()) it = zero.begin();
        int nxt = *it;
        int lst = it == zero.begin() ? *zero.rbegin() : *prev(it);
        sep.erase(mp(getdis(lst, nxt), nxt));
        sep.insert(mp(getdis(lst, pos), pos));
        sep.insert(mp(getdis(pos, nxt), nxt));
        zero.insert(pos);
    }

    int pos = sep.rbegin()->S;
    if(zero.size() == 1){
        sep.clear();
        zero.clear();
    }
    else{
        auto it = zero.lower_bound(pos);
        int nxt = next(it) == zero.end() ? *zero.begin() : *next(it);
        int lst = it == zero.begin() ? *zero.rbegin() : *prev(it);
        sep.erase(mp(getdis(lst, pos), pos));
        sep.erase(mp(getdis(pos, nxt), nxt));
        sep.insert(mp(getdis(lst, nxt), nxt));
        zero.erase(pos);
    }

    use[pos] = true;
    rk[pos] = _rk;
    modify(pos - K + 1, pos - 1, -1);
}

vector<int> ans;
vector<vector<ll>> ri, le;

void init(int k, vector<int> _r){
    K = k;
    rec = _r;
    n = rec.size();
    st.resize(4 * n);
    use.resize(n);
    rk.resize(n);
    ans.resize(n);
    build(rec);

    for(int i = n - 1; i >= 0; i--){
        solve(i);
    }

    le.resize(20, vector<ll>(n));
    ri.resize(20, vector<ll>(n));
    
    {
        vector<int> tmp(n, 1);
        build(tmp);
    }
    vector<int> pos(n);
    for(int i = 0; i < n; i++) pos[rk[i]] = i;
    
    for(int i = 0; i < n; i++){
        Node tmp = query(pos[i] + 1, pos[i] + k - 1);
        if(tmp.mn != 1){
            int nxt = tmp.pos;
            ri[0][pos[i]] = getdis(pos[i], nxt);
            /*cerr << "right " << pos[i] << " : " << nxt << "\n";
            cerr << pos[i] + 1 << " " << pos[i] + k - 1 << "\n";*/
        }
        tmp = query(pos[i] - k + 1, pos[i] - 1);
        if(tmp.mn != 1){
            int nxt = tmp.pos;
            le[0][pos[i]] = getdis(nxt, pos[i]);
            /*cerr << "left " << pos[i] << " : " << nxt << "\n";
            cerr << pos[i] - k + 1 << " " << pos[i] - 1 << "\n";*/
        }
        modify(pos[i], pos[i], -i);
    }
    
    for(int i = 1; i < 20; i++){
        for(int j = 0; j < n; j++){
            int nxt = j - le[i - 1][j];
            nxt = (nxt % n + n) % n;
            le[i][j] = le[i - 1][j] + le[i - 1][nxt];

            nxt = j + ri[i - 1][j];
            nxt = nxt % n;
            ri[i][j] = ri[i - 1][j] + ri[i - 1][nxt];
        }
    }

    /*cerr << "rank ";
    printv(rk, cerr);
    cerr << "left ";
    printv(le[0], cerr);
    cerr << "right ";
    printv(ri[0], cerr);*/

}

bool checkgreater(int x, int y){
    // right
    {
        int dis = getdis(x, y);
        ll tmp = 0;
        int now = x;
        for(int i = 19; i >= 0; i--){
            if(tmp + ri[i][now] >= dis - K + 1) continue;
            tmp += ri[i][now];
            now = (x + tmp) % n;
        }
        if(tmp < dis - K + 1){
            tmp += ri[0][now];
            now = (x + tmp) % n;
        }
        if(tmp >= dis - K + 1 && rk[now] > rk[y]) return true;
    }
    // left
    {
        int dis = getdis(y, x);
        ll tmp = 0;
        int now = x;
        for(int i = 19; i >= 0; i--){
            if(tmp + le[i][now] >= dis - K + 1) continue;
            tmp += le[i][now];
            now = ((x - tmp) % n + n) % n;
        }
        if(tmp < dis - K + 1){
            tmp += le[0][now];
            now = ((x - tmp) % n + n) % n;
        }
        if(tmp >= dis - K + 1 && rk[now] > rk[y]) return true;
    }
    return false;
}

int compare_plants(int x, int y){
    if(checkgreater(x, y)) return 1;
    if(checkgreater(y, x)) return -1;
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 1 ms 264 KB Output is correct
6 Correct 157 ms 3036 KB Output is correct
7 Correct 361 ms 11124 KB Output is correct
8 Correct 1486 ms 80832 KB Output is correct
9 Correct 1430 ms 80852 KB Output is correct
10 Correct 1442 ms 81276 KB Output is correct
11 Correct 1414 ms 82636 KB Output is correct
12 Correct 1385 ms 80476 KB Output is correct
13 Correct 1070 ms 81896 KB Output is correct
14 Correct 1519 ms 80220 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 4 ms 740 KB Output is correct
7 Correct 75 ms 5088 KB Output is correct
8 Correct 3 ms 340 KB Output is correct
9 Correct 5 ms 756 KB Output is correct
10 Correct 79 ms 4984 KB Output is correct
11 Correct 75 ms 4944 KB Output is correct
12 Correct 137 ms 5184 KB Output is correct
13 Correct 82 ms 5084 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 4 ms 740 KB Output is correct
7 Correct 75 ms 5088 KB Output is correct
8 Correct 3 ms 340 KB Output is correct
9 Correct 5 ms 756 KB Output is correct
10 Correct 79 ms 4984 KB Output is correct
11 Correct 75 ms 4944 KB Output is correct
12 Correct 137 ms 5184 KB Output is correct
13 Correct 82 ms 5084 KB Output is correct
14 Correct 144 ms 10860 KB Output is correct
15 Correct 899 ms 80092 KB Output is correct
16 Correct 176 ms 13084 KB Output is correct
17 Correct 863 ms 83936 KB Output is correct
18 Correct 832 ms 85024 KB Output is correct
19 Correct 934 ms 84004 KB Output is correct
20 Correct 800 ms 83996 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 123 ms 3788 KB Output is correct
4 Correct 1098 ms 80592 KB Output is correct
5 Correct 1105 ms 81528 KB Output is correct
6 Correct 1036 ms 80300 KB Output is correct
7 Correct 1030 ms 80304 KB Output is correct
8 Correct 877 ms 80212 KB Output is correct
9 Correct 890 ms 84856 KB Output is correct
10 Correct 1002 ms 84548 KB Output is correct
11 Correct 817 ms 84656 KB Output is correct
12 Correct 1392 ms 83396 KB Output is correct
13 Correct 911 ms 84508 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 1 ms 212 KB Output is correct
6 Correct 4 ms 396 KB Output is correct
7 Correct 37 ms 980 KB Output is correct
8 Correct 16 ms 980 KB Output is correct
9 Correct 28 ms 960 KB Output is correct
10 Correct 17 ms 980 KB Output is correct
11 Correct 35 ms 964 KB Output is correct
12 Correct 30 ms 944 KB Output is correct
13 Correct 13 ms 980 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 3 ms 596 KB Output is correct
6 Correct 924 ms 80440 KB Output is correct
7 Correct 880 ms 80428 KB Output is correct
8 Correct 763 ms 80212 KB Output is correct
9 Correct 827 ms 80212 KB Output is correct
10 Correct 1034 ms 83900 KB Output is correct
11 Correct 822 ms 83896 KB Output is correct
12 Correct 841 ms 83032 KB Output is correct
13 Correct 932 ms 83572 KB Output is correct
14 Correct 773 ms 82632 KB Output is correct
15 Correct 853 ms 82880 KB Output is correct
16 Correct 887 ms 83624 KB Output is correct
17 Correct 1050 ms 82844 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 1 ms 264 KB Output is correct
6 Correct 157 ms 3036 KB Output is correct
7 Correct 361 ms 11124 KB Output is correct
8 Correct 1486 ms 80832 KB Output is correct
9 Correct 1430 ms 80852 KB Output is correct
10 Correct 1442 ms 81276 KB Output is correct
11 Correct 1414 ms 82636 KB Output is correct
12 Correct 1385 ms 80476 KB Output is correct
13 Correct 1070 ms 81896 KB Output is correct
14 Correct 1519 ms 80220 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 0 ms 212 KB Output is correct
18 Correct 0 ms 212 KB Output is correct
19 Correct 1 ms 340 KB Output is correct
20 Correct 4 ms 740 KB Output is correct
21 Correct 75 ms 5088 KB Output is correct
22 Correct 3 ms 340 KB Output is correct
23 Correct 5 ms 756 KB Output is correct
24 Correct 79 ms 4984 KB Output is correct
25 Correct 75 ms 4944 KB Output is correct
26 Correct 137 ms 5184 KB Output is correct
27 Correct 82 ms 5084 KB Output is correct
28 Correct 144 ms 10860 KB Output is correct
29 Correct 899 ms 80092 KB Output is correct
30 Correct 176 ms 13084 KB Output is correct
31 Correct 863 ms 83936 KB Output is correct
32 Correct 832 ms 85024 KB Output is correct
33 Correct 934 ms 84004 KB Output is correct
34 Correct 800 ms 83996 KB Output is correct
35 Correct 0 ms 212 KB Output is correct
36 Correct 0 ms 212 KB Output is correct
37 Correct 123 ms 3788 KB Output is correct
38 Correct 1098 ms 80592 KB Output is correct
39 Correct 1105 ms 81528 KB Output is correct
40 Correct 1036 ms 80300 KB Output is correct
41 Correct 1030 ms 80304 KB Output is correct
42 Correct 877 ms 80212 KB Output is correct
43 Correct 890 ms 84856 KB Output is correct
44 Correct 1002 ms 84548 KB Output is correct
45 Correct 817 ms 84656 KB Output is correct
46 Correct 1392 ms 83396 KB Output is correct
47 Correct 911 ms 84508 KB Output is correct
48 Correct 0 ms 212 KB Output is correct
49 Correct 0 ms 212 KB Output is correct
50 Correct 0 ms 212 KB Output is correct
51 Correct 0 ms 212 KB Output is correct
52 Correct 1 ms 212 KB Output is correct
53 Correct 4 ms 396 KB Output is correct
54 Correct 37 ms 980 KB Output is correct
55 Correct 16 ms 980 KB Output is correct
56 Correct 28 ms 960 KB Output is correct
57 Correct 17 ms 980 KB Output is correct
58 Correct 35 ms 964 KB Output is correct
59 Correct 30 ms 944 KB Output is correct
60 Correct 13 ms 980 KB Output is correct
61 Correct 241 ms 5556 KB Output is correct
62 Correct 471 ms 13172 KB Output is correct
63 Correct 1749 ms 83760 KB Output is correct
64 Correct 1114 ms 83428 KB Output is correct
65 Correct 1086 ms 83524 KB Output is correct
66 Correct 983 ms 83756 KB Output is correct
67 Correct 852 ms 83888 KB Output is correct
68 Correct 1319 ms 84884 KB Output is correct
69 Correct 962 ms 84748 KB Output is correct
70 Correct 1180 ms 84420 KB Output is correct
71 Correct 1282 ms 84048 KB Output is correct
72 Correct 1057 ms 83640 KB Output is correct
73 Correct 967 ms 83776 KB Output is correct
74 Correct 1479 ms 83564 KB Output is correct
75 Correct 985 ms 83732 KB Output is correct