Codeforces 1080F Katya and Segments Sets 主席树

Katya and Segments Sets

感觉好久没打代码了。。写个主席树debug半天。。

按r排序, 用主席树维护当前为止, 每个种类的集合的 l 的最大值的最小值。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 3e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}


int n, m, k;
int hs[N], tot;
int seg[N][3];
vector<int> segv[N];

int treeNum;
int Rt[N];

struct Node {
    int mn;
    int ls, rs;
} Tree[N * 25];


void update(int p, int val, int l, int r, int &x, int y) {
    x = ++treeNum;
    Tree[x] = Tree[y];
    if(l == r) {
        chkmax(Tree[x].mn, val);
        return;
    }
    int mid = l + r >> 1;
    if(p <= mid) update(p, val, l, mid, Tree[x].ls, Tree[y].ls);
    else update(p, val, mid + 1, r, Tree[x].rs, Tree[y].rs);
    Tree[x].mn = min(Tree[Tree[x].ls].mn, Tree[Tree[x].rs].mn);
}

int query(int L, int R, int l, int r, int rt) {
    if(L <= l && r <= R) return Tree[rt].mn;
    int mid = l + r >> 1;
    int ans = inf;
    if(L <= mid) chkmin(ans, query(L, R, l, mid, Tree[rt].ls));
    if(R > mid) chkmin(ans, query(L, R, mid + 1, r, Tree[rt].rs));
    return ans;
}

int getPos(int x) {
    return lower_bound(hs + 1, hs + 1 + tot, x) - hs;
}

int main() {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= k; i++) {
        scanf("%d%d%d", &seg[i][0], &seg[i][1], &seg[i][2]);
        hs[++tot] = seg[i][1];
    }
    sort(hs + 1, hs + 1 + tot);
    tot = unique(hs + 1, hs + 1 + tot) - hs - 1;

    for(int i = 1; i <= k; i++) {
        segv[getPos(seg[i][1])].push_back(i);
    }

    for(int i = 1; i <= tot; i++) {
        int id = segv[i][0];
        update(seg[id][2], seg[id][0], 1, n, Rt[i], Rt[i - 1]);
        for(int j = 1; j < SZ(segv[i]); j++) {
            id = segv[i][j];
            update(seg[id][2], seg[id][0], 1, n, Rt[i], Rt[i]);
        }
    }
    while(m--) {
        int a, b, x, y;
        scanf("%d%d%d%d",&a, &b, &x, &y);
        bool flag;
        y = getPos(y + 1) - 1;
        if(!y) flag = false;
        else {
            int to = query(a, b, 1, n, Rt[y]);
            if(to >= x) flag = true;
            else flag = false;
        }
        puts(flag ? "yes" : "no");
        fflush(stdout);
    }
    return 0;
}

/*
*/