卧薪尝胆,厚积薄发。
Polycarp's New Job
Date: Sat Jan 12 11:12:27 CST 2019 In Category: NoCategory

Description:

支持插入一个 $x\times y$ 的矩形,或者询问当前所有矩形是否都可以放进一个 $h\times w$ 的矩形中,可以重叠和旋转 $90^\circ$ 。
$1\leqslant n\leqslant 5\times 10^5$

Solution:

用一棵线段树维护,线段树下标为 $x$ ,维护 $y$ 的最大值,在询问的时候,假设 $h<w$ ,如果历史最大的 $x$ 或 $y$ 比当前这个 $w$ 大显然不行,然后 $x\in[1,h]$ 一定是 $x$ 放到 $h$ 这一维,因为他们这样能放到小的那一维,如果旋转了一定不优,因为 $w\geqslant h$ 更有可能放更多的, $x\in[h+1,\infty]$ 一定是旋转的放的,因为不旋转一定放不进去,所以用线段树维护一下 $y$ 最大值就可以判断了。

Code:


#include<bits/stdc++.h>
using namespace std;
char getc()
{
register char c = getchar();
while(c != '+' && c != '?')c = getchar();
return c;
}
int n;
#define MAXN 500010
struct node
{
int lc,rc;
int maxv;
node(){maxv = 0;}
}t[MAXN * 35];
int ptr = 0;
int newnode(){return ++ptr;}
int root;
#define mid ((l + r) >> 1)
void add(int &rt,int p,int k,int l,int r)
{
if(rt == 0)rt = newnode();
if(l == r)
{
t[rt].maxv = max(t[rt].maxv,k);
return;
}
if(p <= mid)add(t[rt].lc,p,k,l,mid);
else add(t[rt].rc,p,k,mid + 1,r);
t[rt].maxv = max(t[t[rt].lc].maxv,t[t[rt].rc].maxv);
return;
}
int query(int rt,int L,int R,int l,int r)
{
if(L > R)return 0;
if(rt == 0)return 0;
if(L <= l && r <= R)return t[rt].maxv;
int res = 0;
if(L <= mid)res = max(res,query(t[rt].lc,L,R,l,mid));
if(R > mid)res = max(res,query(t[rt].rc,L,R,mid + 1,r));
return res;
}
#define N 1000000000
int main()
{
scanf("%d",&n);
char opt;
int x,y;
int maxv = 0;
for(int i = 1;i <= n;++i)
{
opt = getc();
cin >> x >> y;
if(opt == '+')
{
maxv = max(maxv,max(x,y));
add(root,x,y,1,N);
}
else
{
if(x > y)swap(x,y);
int lm = query(root,1,x,1,N);
int rm = query(root,x + 1,N,1,N);
if(lm > y || rm > x)
{
cout << "NO" << endl;
continue;
}
if(maxv > y)
{
cout << "NO" << endl;
continue;
}
cout << "YES" << endl;
}
}


return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡