A. Glass Carving
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Leonid wants to become a glass carver (the person who creates beautiful artworks by cutting the glass). He already has a rectangular wmm  ×  h mm sheet of glass, a diamond glass cutter and lots of enthusiasm. What he lacks is understanding of what to carve and how.

In order not to waste time, he decided to practice the technique of carving. To do this, he makes vertical and horizontal cuts through the entire sheet. This process results in making smaller rectangular fragments of glass. Leonid does not move the newly made glass fragments. In particular, a cut divides each fragment of glass that it goes through into smaller fragments.

After each cut Leonid tries to determine what area the largest of the currently available glass fragments has. Since there appear more and more fragments, this question takes him more and more time and distracts him from the fascinating process.

Leonid offers to divide the labor — he will cut glass, and you will calculate the area of the maximum fragment after each cut. Do you agree?

Input

The first line contains three integers w, h, n (2 ≤ w, h ≤ 200 000, 1 ≤ n ≤ 200 000).

Next n lines contain the descriptions of the cuts. Each description has the form H y or V x. In the first case Leonid makes the horizontal cut at the distance y millimeters (1 ≤ y ≤ h - 1) from the lower edge of the original sheet of glass. In the second case Leonid makes a vertical cut at distance x (1 ≤ x ≤ w - 1) millimeters from the left edge of the original sheet of glass. It is guaranteed that Leonid won't make two identical cuts.

Output

After each cut print on a single line the area of the maximum available glass fragment in mm2.

Sample test(s)
input
4 3 4
H 2
V 2
V 3
V 1
output
8
4
4
2
input
7 6 5
H 4
V 3
V 5
H 2
V 1
output
28
16
12
6
4
Note

Picture for the first sample test:

Picture for the second sample test:

 
 
题目意思:
一个w*h的矩形,然后用水平线和竖直线切割,每次切割后输出最大的子面积。
 
思路:
很明显最大子面积是横着最大的长度*竖着最大的长度,那么建两棵线段树,每个区间lx、rx、maxh分别为离该区间左端点最近的已经切割过的点、离右端点最近的已经切割过的点、最长的切割长度。维护这三个值就行了。代码略丑。
 
代码:
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 200005
#define ll root<<1
#define rr root<<1|1
#define mid1 (a[root].l+a[root].r)/2
#define mid2 (b[root].l+b[root].r)/2 int w, h, n;
struct node{
int l, r;
int lx, rx;
int maxh;
}a[N*], b[N*]; void build1(int l,int r,int root){
a[root].l=l;
a[root].r=r;
if(l==r){
if(l==) a[root].lx=a[root].rx=;
else if(l==w) a[root].lx=a[root].rx=w;
else a[root].lx=a[root].rx=-;
a[root].maxh=;
return;
}
build1(l,mid1,ll);
build1(mid1+,r,rr);
a[root].lx=a[ll].lx;
a[root].rx=a[rr].rx;
a[root].maxh=a[root].r-a[root].l;
} void build2(int l,int r,int root){
b[root].l=l;
b[root].r=r;
if(l==r){
if(l==) b[root].lx=b[root].rx=;
else if(l==h) b[root].lx=b[root].rx=h;
else b[root].lx=b[root].rx=-;
b[root].maxh=;
return;
}
build2(l,mid2,ll);
build2(mid2+,r,rr);
b[root].lx=b[ll].lx;
b[root].rx=b[rr].rx;
b[root].maxh=b[root].r-b[root].l;
} void update1(int p,int root){
if(a[root].l==p&&a[root].r==p){
a[root].lx=a[root].rx=p;return;
}
if(p<=a[ll].r) update1(p,ll);
else update1(p,rr);
int ln, rn;
if(a[ll].lx!=-) a[root].lx=a[ll].lx;
else if(a[ll].rx!=-) a[root].lx=a[ll].rx;
else if(a[rr].lx!=-) a[root].lx=a[rr].lx;
else if(a[rr].rx!=-) a[root].lx=a[rr].rx;
else a[root].lx=-; if(a[rr].rx!=-) a[root].rx=a[rr].rx;
else if(a[rr].lx!=-) a[root].rx=a[rr].lx;
else if(a[ll].rx!=-) a[root].rx=a[ll].rx;
else if(a[ll].lx!=-) a[root].rx=a[ll].lx;
else a[root].rx=-; if(a[ll].rx!=-) ln=a[ll].r-a[ll].rx;
else ln=a[ll].r-a[ll].l;
if(a[rr].lx!=-) rn=a[rr].lx-a[rr].l;
else rn=a[rr].r-a[rr].l; a[root].maxh=max(max(a[ll].maxh,a[rr].maxh),ln+rn+);
} void update2(int p,int root){
if(b[root].l==p&&b[root].r==p){
b[root].lx=b[root].rx=p;return;
}
if(p<=b[ll].r) update2(p,ll);
else update2(p,rr);
int ln, rn;
if(b[ll].lx!=-) b[root].lx=b[ll].lx;
else if(b[ll].rx!=-) b[root].lx=b[ll].rx;
else if(b[rr].lx!=-) b[root].lx=b[rr].lx;
else if(b[rr].rx!=-) b[root].lx=b[rr].rx;
else b[root].lx=-; if(b[rr].rx!=-) b[root].rx=b[rr].rx;
else if(b[rr].lx!=-) b[root].rx=b[rr].lx;
else if(b[ll].rx!=-) b[root].rx=b[ll].rx;
else if(b[ll].lx!=-) b[root].rx=b[ll].lx;
else b[root].rx=-;
if(b[ll].rx!=-) ln=b[ll].r-b[ll].rx;
else ln=b[ll].r-b[ll].l;
if(b[rr].lx!=-) rn=b[rr].lx-b[rr].l;
else rn=b[rr].r-b[rr].l;
b[root].maxh=max(max(b[ll].maxh,b[rr].maxh),ln+rn+);
} main()
{
int i, j, k;
while(scanf("%d %d %d",&w,&h,&n)==){
char s[];
build1(,w,);
build2(,h,);
// printf("%d %d\n",a[1].maxh,b[1].maxh);
while(n--){
scanf("%s%d",s,&k);
if(s[]=='H'){
update2(k,);
}
else{
update1(k,);
}
// printf("%d %d\n",a[1].maxh,b[1].maxh);
printf("%I64d\n",(__int64)a[].maxh*(__int64)b[].maxh);
}
}
}

CF #296 (Div. 1) A. Glass Carving 线段树的更多相关文章

  1. Codeforces Round #296 (Div. 1) A. Glass Carving Set的妙用

    A. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. Codeforces Round #296 (Div. 2) C. Glass Carving [ set+multiset ]

    传送门 C. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  3. CF 552(div 3) E Two Teams 线段树,模拟链表

    题目链接:http://codeforces.com/contest/1154/problem/E 题意:两个人轮流取最大值与旁边k个数,问最后这所有的数分别被谁给取走了 分析:看这道题一点思路都没有 ...

  4. [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

    题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi ...

  5. CF 666E Forensic Examination 【SAM 倍增 线段树合并】

    CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t ...

  6. Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并

    D. Developing Game   Pavel is going to make a game of his dream. However, he knows that he can't mak ...

  7. Codeforces Round #275 Div.1 B Interesting Array --线段树

    题意: 构造一个序列,满足m个形如:[l,r,c] 的条件. [l,r,c]表示[l,r]中的元素按位与(&)的和为c. 解法: 线段树维护,sum[rt]表示要满足到现在为止的条件时该子树的 ...

  8. CF 197 DIV2 Xenia and Bit Operations 线段树

    线段树!!1A 代码如下: #include<iostream> #include<cstdio> #define lson i<<1 #define rson i ...

  9. Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

    B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/pro ...

随机推荐

  1. Win10 + Nginx 1.10 + PHP 7 + Redis 配置方法

    软件包版本 软件 版本 - 链接 - Nginx nginx-x32-1.10.2.zip 下载 PHP php-7.0.12-nts-Win32-VC14-x64 下载 Redis php_redi ...

  2. VC++ 回调函数及使用方法(转)

    转载:http://blog.csdn.net/vsooda/article/details/7435801 转载:http://blog.csdn.net/lincyang/article/deta ...

  3. ajax 无刷新上传

    最近要做微信的图文上传,因为一个图文了表中可以有多个图文,所有按钮需要随时添加,所以做了一种无刷新上传的方法. 首先我们要在html页面中写上这样的几段代码 javascript: $(functio ...

  4. Sprint第三阶段(第四天12.12)

  5. div居中方法

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. 在tomcat中配置jdk的不同版本

    在tomcat中配置jdk的不同版本---------------------------------------------------------------------------------- ...

  7. 程序设计入门——C语言 第6周编程练习 2 完数(5分)

    2 完数(5分) 题目内容: 一个正整数的因子是所有可以整除它的正整数.而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数.例如6=1+2+3(6的因子是1,2,3). 现在,你要写一个程序, ...

  8. iOS开发 贝塞尔曲线

    iOS开发 贝塞尔曲线UIBezierPath - 陌云 时间 2014-03-14 11:04:00  博客园-所有随笔区 原文  http://www.cnblogs.com/moyunmo/p/ ...

  9. SQL Server Reporting Service(SSRS) 第三篇 SSRS Matrix用法

    以前不是太清楚SSRS的功能,自从最近有了了解之后,发现它的功能的确很强大.对于Matrix,刚开始我竟不知道它到底有什么用,现将通过一个例子中去理解Matrix,以及和分组Group结合使用的便利性 ...

  10. BWT压缩算法(Burrows-Wheeler Transform)

    参考: BWT (Burrows–Wheeler_transform)数据转换算法 压缩技术主要的工作方式就是找到重复的模式,进行紧密的编码. BWT(Burrows–Wheeler_transfor ...