본문 바로가기

BOJ

[BOJ 17082] 쿼리와 쿼리

https://www.acmicpc.net/problem/17082

 

17082번: 쿼리와 쿼리

첫 쿼리 이후, 배열은 [-2, 1, 0, 2, -1] 이다. 쿼리 놀이를 [1,4], [2,2] 와 같이 하면 종이에는 [2, 1]이 적히게 되고, 이 중 최댓값은 2이다. 다른 방식으로 쿼리 놀이를 하더라도 종이에 적힌 최댓값을

www.acmicpc.net

Tag : greedy

 

문제요약

배열 L, R에서 각각 구간의 왼쪽 끝, 오른쪽 끝을 뽑아서 구간을 M개 만드는데 

이때 max( 구간의 max )를 최소화 하는게 목표다. 지문에서 max( 구간의 max ) 이런 식으로 설명했는데 

그냥 구간들에서 최대 뽑으라는 말이다.

 

풀이

일단 반드시 포함되는 구간이 있다.

L, R을 정렬했을 때 [L_i, R_i]들은 무슨 짓을 해도 구간에 포함된다.

이것들을 제외하고 다른 점들은 최대한 배제시키는 것이 이득인 것을 쉽게 할 수 있다. 

a < b < c < d일 때 구간 [a, c]와 [b, d]를 고르는 것은 항상 [a, b], [c, d]를 고르는 것보다 이득일 수 없다.

항상 포함되는 구간은 전처리를 할 수 있고 이제 쿼리마다 구간에서 빠지는 값과 새로 들어오는 값을 잘 관리해주면 된다.

 

+ 1등 먹으려고 첨부터 set을 pq로 대체하고 짜다가 디버깅을 몇시간했다..

 

 

전체코드

#include "bits/stdc++.h"
#define endl '\n'

using namespace std;
using ll = long long;

int n, m, q;
int a[202020];
int in[202020];
int ltor[202020];
vector<int> l, r, idx;
vector<pair<int, int>> range;
priority_queue<int> ans;
priority_queue<int> del;

#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
int z[36];
char*c=(char*)mmap(0,z[12],1,2,0,fstat(0,(struct stat *)z));
inline int f(){int x=0;bool e;c+=e=*c=='-';while(*c>='0')x=10*x+*c++-'0';c++;return e?-x:x;}
char O[2000000],*d=O;
template<class T> inline void p(T x) {
    if(x<0) *d++='-', x=-x;
    char t[16], *q=t;
    do *q++=x%10|48; while(x/=10);
    do *d++=*--q; while(q!=t);
    *d++=10;
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    
    n = f(); m = f(); q = f();
    for(int i=1; i<=n; i++) a[i] = f();
    l.resize(m); r.resize(m);
    for(auto &i : l) i = f();
    for(auto &i : r) i = f();
    sort(l.begin(), l.end()); sort(r.begin(), r.end());
    for(int i=0; i<m; i++) {
        ltor[l[i]] = max(ltor[l[i]], r[i]);
        if(l[i] > r[i]) {
            for(int j=0; j<q; j++) cout << "1000000000" << endl;
            return 0;
        }
    }
    for(int i=1; i<=n; i++) if(ltor[i]) idx.push_back(i);
    for(int i=0,j; i<idx.size(); i=j+1) {
        j = i;
        while(j + 1 < idx.size() and idx[j + 1] <= ltor[idx[j]]) j++;
        range.push_back({idx[i], ltor[idx[j]]});
    }
    for(auto &[l, r] : range) for(int i=l; i<=r; i++) in[i] = 1;
    for(int i=1; i<=n; i++) if(in[i]) ans.push(a[i]);
    while(q--) {
        int x = f(), y = f();
        if(in[x] and in[y] == 0) {
            del.push(a[x]);
            ans.push(a[y]);
        }
        if(in[x] == 0 and in[y]) {
            del.push(a[y]);
            ans.push(a[x]);
        }
        swap(a[x], a[y]);
        while(ans.size() and del.size() and ans.top() == del.top()) {
            ans.pop();
            del.pop();
        }
        cout << ans.top() << endl;
    }
}

 

'BOJ' 카테고리의 다른 글

[BOJ 2251] 물통  (0) 2022.01.08
[BOJ 3568] 방정식  (0) 2022.01.08
[BOJ 2379] 트리 탐색하기  (0) 2022.01.08
[BOJ 20930] 우주 정거장  (0) 2022.01.08
[BOJ 22954] 그래프 트리 분할  (0) 2022.01.08