답안 #680603

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
680603 2023-01-11T10:39:40 Z someone 식물 비교 (IOI20_plants) C++14
컴파일 오류
0 ms 0 KB
#include <bits/stdc++.h>
#include "plants.h"
#define int long long
#define deb first
#define fin second
#define mid ((deb + fin) >> 1)
using namespace std;

const int M = 1 << 19, N = 2 * M, T = 19, INF = 1e9 + 42;

int n, k, vals[N], corr[N], gauche[T][M], droite[T][M];

set<int> pos0, posMin;
int imin[N], nbInf[N], lazy[N], maxi[N];

void set0(int i, bool is0) {
    if(is0) {
        auto it = pos0.lower_bound(i);
        if((*it) <= i + k)
            posMin.erase((*it));
        it--;
        if(i > (*it) + k && n <= i && i < 2*n)
            posMin.insert(i);
        pos0.insert(i);
    } else {
        pos0.erase(i);
        posMin.erase(i);
        auto it = pos0.lower_bound(i);
        int nex = (*it);
        it--;
        if(nex > (*it) + k && n <= nex && nex < 2*n)
            posMin.insert(nex);
    }
}

inline void applyOp(int i, int add) {
    lazy[i] += add;
    nbInf[i] += add;
}

pair<int, int> update(int i, int deb, int fin, int l, int r, int add) {
    if(r <= deb || fin <= l)
        return {INF, -1};
    if(l <= deb && fin <= r) {
        applyOp(i, add);
        return {nbInf[i], imin[i]};
    }
    applyOp(i*2, lazy[i]);
    applyOp(i*2+1, lazy[i]);
    auto ans = min(update(i*2, deb, mid, l, r, add),
                   update(i*2+1, mid, fin, l, r, add));
                   
    lazy[i] = 0;
    nbInf[i] = min(nbInf[i*2], nbInf[i*2+1]);
    if(nbInf[i] == nbInf[i*2])
        imin[i] = imin[i*2];
    else
        imin[i] = imin[i*2+1];
    return ans;
}

void setMax(int i, int val) {
    i += M;
    while(i) {
        maxi[i] = max(maxi[i], val);
        i >>= 1;
    }
}

int getMax(int i, int deb, int fin, int l, int r) {
    if(r <= deb || fin <= l)
        return 0;
    if(l <= deb && fin <= r)
        return maxi[i];
    return max(getMax(i*2, deb, mid, l, r), getMax(i*2+1, mid, fin, l, r));
}

inline int getId(int i) {
    while(i < 0)
        i += n;
    while(i >= n)
        i -= n;
    return i;
}

void init(int K, vector<int> r) {
    k = K;
    pos0.insert(INF);
    pos0.insert(-INF);
    
    k--;
    n = (int)r.size();
    for(int i = M; i < N; i++)
        imin[i] = i - M;
    for(int i = M-1; i > 0; i--)
        imin[i] = imin[i*2];
    
    for(int i = 0; i < n; i++) {
        r[i] = k - r[i];
        update(1, 0, M, i, i+1, r[i]);
        if(r[i] == 0) {
            set0(i, 1);
            set0(i + n, 1);
        }
    }
    
    for(int i = 0; i < n; i++) {
        int id = getId((*posMin.begin()));
        update(1, 0, M, id, id+1, INF);
        
        set0(id, 0);
        set0(id + n, 0);
        vals[id] = i+1;
        corr[i+1] = id;
        
        corr[0] = id;
        setMax(id, i+1);
        setMax(id + n, i+1);
        gauche[0][id] = getId(corr[getMax(1, 0, M, id + n - k, id + n)] - id),
        droite[0][id] = getId(corr[getMax(1, 0, M, id + 1, id + k + 1)] - id);
        if(gauche[0][id] > 0)
            gauche[0][id] -= n;
        
        if(id >= k) {
            update(1, 0, M, id - k, id, -1);
        } else {
            update(1, 0, M, 0, id, -1);
            update(1, 0, M, n + id - k, n, -1);
        }
        auto pii = update(1, 0, M, 0, n, 0);
        while(pii.first == 0) {
            update(1, 0, M, pii.second, pii.second+1, INF);
            set0(pii.second, 1);
            set0(pii.second + n, 1);
            pii = update(1, 0, M, 0, n, 0);
        }
    }
    
    for(int i = 1; i < T; i++) {
        for(int j = 0; j < n; j++) {
            gauche[i][j] = gauche[i-1][getId(j + gauche[i-1][j])] + gauche[i-1][j];
            droite[i][j] = droite[i-1][getId(j + droite[i-1][j])] + droite[i-1][j];
        }
    }
}

int compare_plants(int x, int y) {
    int ans = 1;
    if(vals[x] < vals[y]) {
        swap(x, y);
        ans = -1;
    }
    int idl = x, idr = x, nbl = 0, nbr = 0;
    for(int i = T-1; i > -1; i--) {
        int l = getId(gauche[i][idl] + idl),
            r = getId(droite[i][idr] + idr);
        if(vals[l] >= vals[y]) {
            nbl += gauche[i][idl];
            idl = l;
        }
        if(vals[r] >= vals[y]) {
            nbr += droite[i][idr];
            idr = r;
        }
    }
    int l = x + nbl, r = x + nbr;
    if((l <= y - n && y - n <= r) || (l <= y && y <= r) || (l <= y + n && y + n <= r))
        return ans;
    return 0;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    int k;
    cin >> k >> n;
    vector<int> r(n);
    for(int i = 0; i < n; i++)
        cin >> r[i];
    init(k, r);
    int q; cin >> q;
    for(int i = 0; i < q; i++) {
        int x, y;
        cin >> x >> y;
        cout << compare_plants(x, y) << '\n';
    }
}

Compilation message

/usr/bin/ld: /tmp/cc32zbU8.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccV4nbM7.o:plants.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/cc32zbU8.o: in function `main':
grader.cpp:(.text.startup+0x2fb): undefined reference to `init(int, std::vector<int, std::allocator<int> >)'
/usr/bin/ld: grader.cpp:(.text.startup+0x347): undefined reference to `compare_plants(int, int)'
collect2: error: ld returned 1 exit status