cf605D. Board Game(BFS tree array set)

Keywords: C++

meaning of the title

Title Link

Each card has four attributes ((a, b, c, d)\), a n d the protagonist has two attributes ((x, y)\) (initially (0, 0)).

A card can be used if and only if \(a < x, B < y \), after use \(x\) becomes \\\\\\\\\\\\\\\

Ask for the minimum number of steps to use the (n) card

Sol

Starting directly from ((0,0)\) with BFS vigorously, the first arrival is the smallest, while recording the precursor

Now the question is how to know which points to choose, that is, to find all points of \\\\\\\\\\\\

Since each element is guaranteed to occur only once, the total complexity is \(O(nlog^2n))

#include<bits/stdc++.h> 
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define pb(x) push_back(x)
// #define int long long 
#define LL long long 
#define pt(x) printf("%d ", x);
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 2e5 + 10, INF = 1e9 + 10, mod = 1e9 + 7;
const double eps = 1e-9;
void chmax(int &a, int b) {a = (a > b ? a : b);}
void chmin(int &a, int b) {a = (a < b ? a : b);}
int sqr(int x) {return x * x;}
int add(int x, int y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
void add2(int &x, int y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
int mul(int x, int y) {return 1ll * x * y % mod;}
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, a[MAXN], b[MAXN], c[MAXN], d[MAXN], vis[MAXN], dis[MAXN], pre[MAXN], da[MAXN], num;
#define lb(x) (x & (-x)) 
#define sit set<Pair>::iterator 
set<Pair> T[MAXN];
void Add(int x, int v, int id) {
    for(; x <= num; x += lb(x)) T[x].insert(MP(v, id));
}
vector<int> Query(int p) {
    int x = a[p], y = b[p];
    vector<int> res;
    for(; x; x -= lb(x)) {
        set<Pair> &now = T[x];
        while(1) {
            sit it = now.lower_bound(MP(y, 0));
            if(it == now.end()) break;
            res.pb(it -> se); now.erase(it);
        }
    }
    return res;
}

void Des() {
    sort(da + 1, da + num + 1); num = unique(da + 1, da + num + 1) - da - 1;
    for(int i = 1; i <= N; i++) {
        a[i] = num - (lower_bound(da + 1, da + num + 1, a[i]) - da) + 1;
        c[i] = num - (lower_bound(da + 1, da + num + 1, c[i]) - da) + 1;
        if(i != N) Add(c[i], d[i], i);
    }
}
void print(int t) {
    printf("%d\n", dis[t]);
    for(int u = t; ~u; u = pre[u]) printf("%d ", u);
}
void BFS() {
    queue<int> q; q.push(N); pre[N] = -1; dis[N] = 1;
    while(!q.empty()) {
        int p = q.front(); q.pop();
        if(a[p] == num && !b[p]) {print(p); return ;}
        vector<int> nxt = Query(p);
        for(int i = 0, t; i < nxt.size(); i++) {
            if(vis[nxt[i]]) continue; vis[nxt[i]] = 1;
            q.push(t = nxt[i]);
            dis[t] = dis[p] + 1, pre[t] = p;
        }
    }
    puts("-1");
}
signed main() {
    N = read(); bool flag = 0;
    for(int i = 1; i <= N; i++) {
        a[i] = read(), b[i] = read(), c[i] = read(), d[i] = read();
        da[++num] = a[i]; 
        da[++num] = c[i];
        flag |= (!a[i] && !b[i]);
    } 
    if(!flag) return puts("-1");
    Des();
    BFS();
    return 0;
}

Posted by jimjack145 on Mon, 21 Jan 2019 12:36:12 -0800