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. EXCLE使用中常用函数和公式

    1.查找重复项 IF(COUNTIF(A:A,A1)>1"重复""") 或者 IF(COUNTIF($A$1:$A$100,A1)=1,"&qu ...

  2. Fragment碎片

    布局文件中添加碎片 1.在onCteate()方法中调用inflater.inflate()加载Fragment布局 2.在xml的<fragment>中需要显示指明碎片名称(androi ...

  3. TCP/IP基础概念及通信过程举例

    TCP/IP基础概念及通信过程举例 出现 上个世纪60年代,由于中央集中式网络的容灾性较弱,以美国国防部为中心的一家组织研究出分组交换网络.后来为了验证分组交换技术的实用性,ARPANET出现了,并且 ...

  4. 景区3D指纹验证系统解决方案

    旅游业已成为全球经济中发展势头最强劲和规模最大的产业之一.旅游业在城市经济发展中的产业地位.经济作用逐步增强,旅游业对城市经济的拉动性.社会就业的带动力.以及对文化与环境的促进作用日益显现.指纹门票为 ...

  5. stst

    静态代码块如果不要static 那么只要生成新的该对象,则会执行{}内的代码 super.onDestroy() 先后顺序问题 Ctrl + Alt + F refromat code目前看来不能对代 ...

  6. Android Device Monitor工具的DDMS使用

    Dalvik Debug Monitor Server(DDMS)是主要的Android调试工具之一 1.打开android studio->tools->android device m ...

  7. eclipse下的,maven+spring+springMVC+mabatis+mysql.创建

    环境:window系统,64位工具:eclipse:下载地址:            链接:http://pan.baidu.com/s/1hr73LE8 密码:vcsa        tomcat: ...

  8. Contiki-一个进程的例子

    进程调度器 进程调度器的作用是调用进程.进程调度器通过调用实现进程线程的函数来调用进程.Contiki中所有的进程被设计为响应传递到进程中的事件,或者相应进程请求的轮询.进程调度器在调度进程的时候会将 ...

  9. select 和 radio 的选中状态

    radio: <script type="text/javascript"> //判断个函数 以上 5 个Radio 那个为选中状态function judgeRadi ...

  10. linux笔记:linux服务管理

    linux服务的分类: 启动和自启动: 查询已经安装的服务: RPM包的默认安装路径: 独立服务的启动: 独立服务的自启动: 基于xinetd的服务的管理: xinetd服务的自启动: 源码包安装服务 ...