卧薪尝胆,厚积薄发。
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;
}
In tag:
数据结构-线段树
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡