题解 CF527C 【Glass Carving】
发布于 2020-11-21
题意
有一个w*h的矩形,每次要么横着切一刀,要么竖着切一刀,每次你都要回答切完后最大的子矩形的面积。
要么是横着在y位置切一刀,要么是竖着在x位置切一刀.
题解
原来想着用暴力写,但是数据范围比较大:2 <= w, h <= 200000, 1 <= n <= 200000。然后就想到了STL。
用两个multiset和两个set分别储存切的痕迹与原来的,面积就是最大的长和宽相乘。
代码
#include<bits/stdc++.h>
#define its set<int>::iterator
#define is mulitset<int>::iterator
using namespace std;
int w,h,n;
multiset<int> sx;
multiset<int> sy;
set<int> x;
set<int> y;
int main(){
scanf("%d%d%d",&w,&h,&n);
x.insert(0);
x.insert(h);
y.insert(w);
y.insert(0);
sx.insert(h);
sy.insert(w);
for(int i=1;i<=n;++i)
{
char c;
int p;
cin>>c;
scanf("%d",&p);
if(c=='V')
{
y.insert(p);
its it,itt;
it=y.lower_bound(p);
itt=y.upper_bound(p);
--it;
int ls,rs;
ls=p-*it;
rs=*itt-p;
int ss=*itt-*it;
//cout<<*itt<<" "<<*it<<" "<<ss<<endl;
sy.erase(sy.find(ss));
sy.insert(ls);
sy.insert(rs);
}
else
{
x.insert(p);
its it,itt;
it=x.lower_bound(p);
itt=x.upper_bound(p);
--it;
int ls,rs;
ls=p-*it;
rs=*itt-p;
int ss=*itt-*it;
//cout<<*itt<<" "<<*it<<" "<<ss<<endl;
sx.erase(sx.find(ss));
sx.insert(rs);
sx.insert(ls);
}
int a,b;
a=*(--sx.end());
b=*(--sy.end());
printf("%lld\n",(1LL)*a*b);
}
return 0;
}