现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
![](https://img.51nod.com/upload/000FBF42/08D2CB5705AB76390000000000000015.png)
对于第四次切割,下面四块玻璃的面积是一样大的。都是2。
Input
单组测试数据。 第一行有三个整数 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在横向上长w 毫米,纵向上长h 毫米,接下来有n次的切割。 接下来有n行输入,每一行描述一次切割。 输入的格式是H y 或 V x。 H y表示横向切割,切割线距离下边缘y毫米(1≤y≤h-1)。 V x表示纵向切割,切割线距离左边缘x毫米(1≤x≤w-1)。 输入保证不会有两次切割是一样的。
Output
对于每一次切割,输出所有玻璃中面积最大的是多少。
Input示例
样例输入1 4 3 4 H 2 V 2 V 3 V 1
Output示例
样例输出1 8 4 4 2
时限1.5s 用线段树区间合并1.4秒艹过去了。。。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include <set>
#include <bits/stdc++.h>
using namespace std;
const int N = 200000+10;
typedef long long LL;
struct node
{
int l, r;
}pw[N<<2], ph[N<<2];
int sum1[N<<2], sum2[N<<2];
void build1(int l,int r,int rt)
{
pw[rt].l=pw[rt].r=-1,sum1[rt]=0;
if(l==r) return ;
int mid=(l+r)/2;
build1(l,mid,rt<<1);
build1(mid+1,r,rt<<1|1);
return ;
}
void update1(int l,int r,int rt,int x)
{
if(l==r)
{
pw[rt].l=pw[rt].r=x;
return ;
}
int mid=(l+r)/2;
if(x<=mid) update1(l,mid,rt<<1,x);
else update1(mid+1,r,rt<<1|1,x);
if(pw[rt<<1].l!=-1) pw[rt].l=pw[rt<<1].l;
else pw[rt].l=pw[rt<<1|1].l;
if(pw[rt<<1|1].r!=-1) pw[rt].r=pw[rt<<1|1].r;
else pw[rt].r=pw[rt<<1].r;
if(pw[rt<<1].l!=-1&&pw[rt<<1].r!=-1) sum1[rt]=sum1[rt<<1];
if(pw[rt<<1|1].l!=-1&&pw[rt<<1|1].r!=-1) sum1[rt]=max(sum1[rt<<1|1],sum1[rt]);
if(pw[rt<<1].r!=-1&&pw[rt<<1|1].l!=-1) sum1[rt]=max(pw[rt<<1|1].l-pw[rt<<1].r,sum1[rt]);
return ;
}
void build2(int l,int r,int rt)
{
ph[rt].l=ph[rt].r=-1;
if(l==r) return ;
int mid=(l+r)/2;
build2(l,mid,rt<<1);
build2(mid+1,r,rt<<1|1);
return ;
}
void update2(int l,int r,int rt,int x)
{
if(l==r)
{
ph[rt].l=ph[rt].r=x;
return ;
}
int mid=(l+r)/2;
if(x<=mid) update2(l,mid,rt<<1,x);
else update2(mid+1,r,rt<<1|1,x);
if(ph[rt<<1].l!=-1) ph[rt].l=ph[rt<<1].l;
else ph[rt].l=ph[rt<<1|1].l;
if(ph[rt<<1|1].r!=-1) ph[rt].r=ph[rt<<1|1].r;
else ph[rt].r=ph[rt<<1].r;
if(ph[rt<<1].l!=-1&&ph[rt<<1].r!=-1) sum2[rt]=sum2[rt<<1];
if(ph[rt<<1|1].l!=-1&&ph[rt<<1|1].r!=-1) sum2[rt]=max(sum2[rt<<1|1],sum2[rt]);
if(ph[rt<<1].r!=-1&&ph[rt<<1|1].l!=-1) sum2[rt]=max(ph[rt<<1|1].l-ph[rt<<1].r,sum2[rt]);
return ;
}
char str[10];
int main()
{
int w, h, n;
scanf("%d %d %d", &w, &h, &n);
build1(0,w,1);
build2(0,h,1);
update1(0,w,1,0);
update1(0,w,1,w);
update2(0,h,1,0);
update2(0,h,1,h);
while(n--)
{
int x;
scanf("%s %d",str, &x);
if(str[0]=='V')
{
update1(0,w,1,x);
}
else
{
update2(0,h,1,x);
}
printf("%lld\n",(LL)sum1[1]*(LL)sum2[1]);
}
return 0;
}