首页 > 其他分享 >【题解】CF44G Shooting Gallery

【题解】CF44G Shooting Gallery

时间:2023-04-30 21:55:23浏览次数:41  
标签:ch cur int 题解 mid mx Shooting my Gallery

题目大意

给定\(n\)个三维空间的平面,由高度\(z\)、\(x\)的范围\([xl,xr]\)和\(y\)的范围\([yl,yr]\)来表示。有\(m\)次射击,每次射击点\((x,y)\),摧毁包含此点的\(z\)值最小的平面,输出此平面编号,若摧毁不了任何平面,输出\(0\)。

题解

点查平面不好做,于是可以转化为平面查点,先将平面按高度排序从小到大,而后查询一个平面内时间最靠前的点,将查到的点删去。
是个裸的kdt板子。

#include <bits/stdc++.h>
using namespace std;
inline int read() {
    int x = 0, flag = 1;
    char ch = getchar();
    for( ; ch > '9' || ch < '0' ; ch = getchar()) if(ch == '-') flag = -1;
    for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
    return x * flag;
}
const int MAXN = 2e5 + 50, B = 317, INF = 998244353;
int n, m, Ans[MAXN], rt, cnt = 0;
int DY[MAXN], Cl = 0;
struct Point {
    int x, y, id;
} P[MAXN];
struct Ques {
    int X1, Y1, X2, Y2, id, h;
} Q[MAXN];
struct Tree {
    int X, Y, Min, ls, rs, dat, fa;
    int mx[2], my[2];
    void clean() {
        X = Y = ls = rs = mx[1] = my[1] = fa = 0;
        mx[0] = my[0] = dat = Min = INF; 
    }
} T[MAXN];
int MIN(int a, int b) { return a < b ? a : b; }
bool cmp3(Point a, Point b) { return a.y < b.y; }
bool cmp2(Point a, Point b) { return a.x < b.x; }
bool cmp(Ques a, Ques b) { return a.h < b.h; }
void update(int cur) {
    T[cur].Min = MIN(T[T[cur].rs].Min, T[T[cur].ls].Min);
    T[cur].Min = MIN(T[cur].Min, T[cur].dat);
    T[cur].mx[0] = MIN(MIN(T[T[cur].rs].mx[0], T[T[cur].ls].mx[0]), T[cur].mx[0]);
    T[cur].my[0] = MIN(MIN(T[T[cur].rs].my[0], T[T[cur].ls].my[0]), T[cur].my[0]);
    T[cur].mx[1] = max(max(T[T[cur].rs].mx[1], T[T[cur].ls].mx[1]), T[cur].mx[1]);
    T[cur].my[1] = max(max(T[T[cur].rs].my[1], T[T[cur].ls].my[1]), T[cur].my[1]);
}
void build(int &cur, int L, int R, int D, int fa) {
    if(L > R) return ;
    if(!cur) cur = ++ cnt;
    int mid = (L + R) >> 1;
    T[cur].fa = fa;
    if(L == R) {
        int x = P[L].x, y = P[L].y;
        T[cur].mx[0] = T[cur].mx[1] = T[cur].X = x;
        T[cur].my[0] = T[cur].my[1] = T[cur].Y = y;
        T[cur].dat = T[cur].Min = P[L].id; 
        DY[P[L].id] = cur;
        return ;
    }
    if(D == 0) nth_element(P + L, P + mid, P + 1 + R, cmp2);
    else nth_element(P + L, P + mid, P + 1 + R, cmp3);
    T[cur].dat = P[mid].id, T[cur].X = P[mid].x, T[cur].Y = P[mid].y;
    T[cur].mx[0] = T[cur].mx[1] = T[cur].X;
    T[cur].my[0] = T[cur].my[1] = T[cur].Y;
    DY[P[mid].id] = cur;
    build(T[cur].ls, L, mid - 1, D ^ 1, cur);
    build(T[cur].rs, mid + 1, R, D ^ 1, cur); 
    update(cur); return ;
}
bool out(int x, int X1, int Y1, int X2, int Y2) { return (T[x].mx[0] > X2 || T[x].mx[1] < X1 || T[x].my[0] > Y2 || T[x].my[1] < Y1); }
bool in(int x, int X1, int Y1, int X2, int Y2) { return (T[x].mx[0] >= X1 && T[x].mx[1] <= X2 && T[x].my[0] >= Y1 && T[x].my[1] <= Y2); }
int query(int now, int X1, int Y1, int X2, int Y2) {
    int Min = INF;
    if(T[now].X >= X1 && T[now].Y >= Y1 && T[now].X <= X2 && T[now].Y <= Y2) Min = T[now].dat;
    if(out(now, X1, Y1, X2, Y2) || !now) return Min;
    if(in(now, X1, Y1, X2, Y2)) return min(T[now].Min, T[now].dat);
    if(T[now].ls) Min = MIN(Min, query(T[now].ls, X1, Y1, X2, Y2));
    if(T[now].rs) Min = MIN(Min, query(T[now].rs, X1, Y1, X2, Y2));
    return Min;
}
void Go(int x, int t) {
    if(! x) return ;
    if(T[x].dat == t) T[x].dat = INF; 
    update(x); Go(T[x].fa, t);
    return ;
}

int main() {
    n = read(); T[0].clean();
    for(int i = 1 ; i <= n ; i ++) Ans[i] = -1;
    for(int i = 1 ; i <= n ; i ++) {
        Q[i].X1 = read(), Q[i].X2 = read();
        Q[i].Y1 = read(), Q[i].Y2 = read();
        Q[i].h = read(), Q[i].id = i;
    } rt = 0;
    m = read();
    sort(Q + 1, Q + 1 + n, cmp);
    for(int i = 1 ; i <= m ; i ++) {
        P[i].x = read(), P[i].y = read();
        P[i].id = i;
    }
    build(rt, 1, m, 0, 0);
    for(int i = 1 ; i <= n; i ++) {
        int t = query(rt, Q[i].X1, Q[i].Y1, Q[i].X2, Q[i].Y2);
        if(t == 998244353 || !t) continue;
        Ans[t] = Q[i].id, Go(DY[t], t);
    }
    for(int i = 1 ; i <= m ; i ++) printf("%d\n", max(Ans[i], 0));
    return 0;
}

标签:ch,cur,int,题解,mid,mx,Shooting,my,Gallery
From: https://www.cnblogs.com/flywatre/p/17365837.html

相关文章

  • Codeforces Round 869 (Div.1 & Div.2) 题解
    2A.Politics因为编号为\(1\)的人一定不会离开,那么最后留下的人一定要和编号为\(1\)的人的所有参数都一致,所以计数即可。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>u......
  • CF51F Caterpillar题解
    题目传送门题意:定义毛毛虫为一种特殊的树,形如一条链上挂着若干个叶子。特殊地,在本题中的毛毛虫允许自环但不允许重边。给定一个无向图,每次操作可以合并两个点以及两个点的出边(两个点有相同出边则出现重边,两个点之间有边则出现自环)。求将其变为毛毛虫的最小操作次数。容易发现,......
  • Windows下安装Docker详细过程及问题解决
    官方手册供参考:https://docs.docker.com/desktop/windows/一:什么是Docker?Docker是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。Dock......
  • 义中常规赛430题解
    T1二分一个删除的数字个数然后考虑删除的数字肯定是从大到小来的,所以预处理一个降序的数组,这样能知道二分的数字个数所对应的数字。在原数组上跑最大子段和,如果碰到大于二分位置的数字就删了。最终成绩26分,因为对于二分的个数mid,原数组中a[mid]不止1个的话,无法判断哪些该删,哪......
  • Android Bitmap内存溢出问题解释
    Android平台在图片处理方面经常会出现OOM的问题,在去年开发的一个项目中,我也一直被这个问题所困扰,在这方面也搜集了许多的资料,今天仅仅针对Android平台的Bitmap说事儿,今后再对内存的问题做详细的探讨,android平台对图片解码这块确实设置的有内存上限,在解码Bitmap的时候android平台会......
  • abc252_d Distinct Trio 题解
    这是数学题耶!题意给定一个整数\(n\)和一个长度为\(n\)的整数序列\(a\),求满足以下要求的三元组个数:\(1\leqslanti<j<k\leqslantn\)。\(a_i\nea_j\),\(a_j\nea_k\),\(a_k\nea_i\)。思路先想正着做,好,不会。正着做不行就反着做,先算出所有情况,再去掉不合法。......
  • ABC G Ex 简要题解
    ABC212GPowerPair推柿子题\(\sum\limits_{x}^{P-1}\sum\limits_{y}^{P-1}\existsn\in\mathbb{N}\x^n\equivy(\bmodP)\)\(1+\sum\limits_{x=1}^{P-1}\sum\limits_{y=1}^{P-1}\existsn\in\mathbb{N}\x^n\equivy(\bmodP)\)考虑模\(P\)......
  • AT_abs300_e 题解
    一、题目描述:你有一个骰子,数字1~6可以被等概率扔到。初始时有一个数$ans=1$。当扔到数字$x$时,$ans=ans\timesx$。给你一个数字$n$,求$ans$能等于$n$的概率。$n<=1e18$。答案对$998244353$取模。 二、解题思路:当扔到$1$时,相当于......
  • 皇后游戏 题解
    luoguP2123题目描述皇后有\(n\)位大臣,每位大臣的左右手上面分别写上了一个正整数。恰逢国庆节来临,皇后决定为\(n\)位大臣颁发奖金,其中第\(i\)位大臣所获得的奖金数目为第\(i-1\)位大臣所获得奖金数目与前\(i\)位大臣左手上的数的和的较大值再加上第\(i\)位大臣右手......
  • 题解
    D.RangeandPartition1800思维https://codeforces.com/contest/1631/problem/D题解:由于严格大于,故其最终前缀和s[n]>=k,而当s[n]>=k,s[0]=0,每步至多下降1,故其中必有至少k个点满足s[i]=x(1<=x<=k),故符合题意,故只需双指针找出最小的满足题意的区间即可。#include<bits/stdc++......