现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
对于第四次切割,下面四块玻璃的面积是一样大的。都是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
线段树--------------
以x,y 分别建线段树---来寻找最大区间
代码:
#include<stdio.h> int max(int x,int y) { if (x>y) return x; return y; } struct Tree{ int l,r,shu,lnode,rnode; }HH[550000],WW[550000]; void createW(int l,int r,int x) { WW[x].l=l;WW[x].r=r; WW[x].shu=r-l; WW[x].lnode=r; WW[x].rnode=l; if (l+1<r) { int m=(l+r)>>1; createW(l,m,x*2); createW(m,r,x*2+1); } } void geW(int x,int p) { if (WW[x].lnode>p) WW[x].lnode=p; if (WW[x].rnode<p) WW[x].rnode=p; WW[x].shu=max(WW[x].r-WW[x].rnode,WW[x].lnode-WW[x].l); if (WW[x].l+1<WW[x].r) { int m=(WW[x].l+WW[x].r)>>1; if (p<=m) geW(x*2,p); if (p>=m) geW(x*2+1,p); WW[x].shu=max(WW[x*2].shu,WW[x*2+1].shu); int a,b; a=WW[x*2].rnode; b=WW[x*2+1].lnode; if (b-a>WW[x].shu) WW[x].shu=b-a; } } void createH(int l,int r,int x) { HH[x].l=l;HH[x].r=r; HH[x].shu=r-l; HH[x].lnode=r; HH[x].rnode=l; if (l+1<r) { int m=(l+r)>>1; createH(l,m,x*2); createH(m,r,x*2+1); } } void geH(int x,int p) { if (HH[x].lnode>p) HH[x].lnode=p; if (HH[x].rnode<p) HH[x].rnode=p; HH[x].shu=max(HH[x].r-HH[x].rnode,HH[x].lnode-HH[x].l); if (HH[x].l+1<HH[x].r) { int m=(HH[x].l+HH[x].r)>>1; if (p<=m) geH(x*2,p); if (p>=m) geH(x*2+1,p); HH[x].shu=max(HH[x*2].shu,HH[x*2+1].shu); int a,b; a=HH[x*2].rnode; b=HH[x*2+1].lnode; if (b-a>HH[x].shu) HH[x].shu=b-a; } } int main() { int w,h,n; scanf("%d%d%d",&w,&h,&n); createW(0,w,1); createH(0,h,1); char ch[5]; int a,b; long long aa,bb; for (int i=0;i<n;i++) { scanf("%s%d",ch,&a); if (ch[0]=='V') geW(1,a); else geH(1,a); aa=WW[1].shu; bb=HH[1].shu; printf("%lld\n",aa*bb); } return 0; }