[codeforces 528]A. Glass Carving

试题描述

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?

输入

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.

输出

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

输入示例

H
V
V
V

输出示例


数据规模及约定

见“输入

题解

不难发现对于任意的长、宽,我们都可以还原出原玻璃板上的一个矩形,所以求最大面积可以转化为分别求最大的长和宽,然后乘起来就是答案。

问题变成了一个一维的:每次在 [0, n] 这个区间内插入不重复的点并询问最长的不包含任何点的线段。不难想到平衡树,因为它可以维护一个点的前驱和后继(不妨设这是平衡树 1 号),那么如何实时维护最长线段呢?我们可以再建一棵平衡树(平衡树 2 号)维护每条线段的长度,那么一次插入操作(插入点 x)不仅要在 1 号中插入一个数并找到其前驱 l 和后继 r,还要在 2 号中删除 r - l 这个长度,并添加 x - l 和 r - x 这两个长度,维护最大值即可。因为要分别维护矩形的长和宽,所以总共要建立 4 棵平衡树。(感觉好有毒。。。)

对于其他人,这题是 STL 水题;对于我,这题是数据结构码农题。。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 1000010
#define LL long long
int n, m, q; struct Node {
int v, r, mn, mx;
Node(): v(0), r(0), mn(0), mx(0) {}
Node(int _, int __, int ___, int ____): v(_), r(__), mn(___), mx(____) {}
} ns[maxn];
int r1, r2, r3, r4, ch[maxn][2], fa[maxn], ToT;
void maintain(int o) {
int l = ch[o][0], r = ch[o][1];
ns[o].mn = ns[o].mx = ns[o].v;
if(l) ns[o].mn = min(ns[o].mn, ns[l].mn), ns[o].mx = max(ns[o].mx, ns[l].mx);
if(r) ns[o].mn = min(ns[o].mn, ns[r].mn), ns[o].mx = max(ns[o].mx, ns[r].mx);
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(ch[y][1] == u) swap(l, r);
if(z) ch[z][ch[z][1]==y] = u;
fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
int xl, xr;
void insert(int& o, int v) {
if(!o) ns[o = ++ToT] = Node(v, rand(), v, v);
else {
int d = (v >= ns[o].v);
// printf("%d %d %d\n", ns[o].v, v, ns[ch[o][d]].mn);
// printf("%d %d %d\n", ns[ch[o][d]].mx, v, ns[o].v);
if(v >= ns[o].v && v <= ns[ch[o][d]].mn) xl = max(xl, ns[o].v), xr = min(xr, ns[ch[o][d]].mn);
if(v <= ns[o].v && v >= ns[ch[o][d]].mx) xl = max(xl, ns[ch[o][d]].mx), xr = min(xr, ns[o].v);
insert(ch[o][d], v);
fa[ch[o][d]] = o;
// printf("bo: %d %d\n", o, ch[o][d]);
if(ns[ch[o][d]].r > ns[o].r) {
int t = ch[o][d];
rotate(ch[o][d]);
o = t;
}
// printf("ao: %d\n", o);
}
return maintain(o);
}
bool del(int& o, int v, int pa) {
if(!o) return 1;
// printf("del: %d %d %d\n", o, ns[o].v, v);
if(ns[o].v == v) {
if(!ch[o][0] && !ch[o][1]) {
fa[o] = ch[o][0] = ch[o][1] = 0, o = 0;
maintain(o);
return 0;
}
if(!ch[o][0]) {
int t = ch[o][1];
fa[o] = ch[o][0] = ch[o][1] = 0, o = t, fa[o] = pa;
maintain(o);
return 0;
}
if(!ch[o][1]) {
int t = ch[o][0];
fa[o] = ch[o][0] = ch[o][1] = 0, o = t, fa[o] = pa;
maintain(o);
return 0;
}
int d = ns[ch[o][1]].r > ns[ch[o][0]].r;
int t = ch[o][d];
rotate(ch[o][d]);
o = t;
del(ch[o][d^1], v, o);
maintain(o);
return 0;
}
int d = (v >= ns[o].v);
if(del(ch[o][d], v, o)) maintain(o), del(ch[o][d^1], v, o);
maintain(o);
return 0;
} int main() {
srand(6);
n = read(); m = read(); q = read(); insert(r1, 0); insert(r1, m);
insert(r2, 0); insert(r2, n);
insert(r3, m); insert(r4, n);
while(q--) {
char tp = getchar();
while(!isalpha(tp)) tp = getchar();
int x = read();
xl = -1; xr = max(n, m) + 1;
if(tp == 'H') {
insert(r1, x);
int l = xl, r = xr;
// printf("f %d %d\n", l, r);
del(r3, r - l, 0);
insert(r3, x - l), insert(r3, r - x);
}
if(tp == 'V') {
insert(r2, x);
int l = xl, r = xr;
// printf("f %d %d\n", l, r);
del(r4, r - l, 0);
insert(r4, x - l), insert(r4, r - x);
}
printf("%I64d\n", (LL)ns[r3].mx * ns[r4].mx);
} return 0;
}

[codeforces 528]A. Glass Carving的更多相关文章

  1. codeforces 527 C Glass Carving

    Glass Carving time limit per test 2 seconds Leonid wants to become a glass carver (the person who cr ...

  2. 【codeforces 527C】Glass Carving

    [题目链接]:http://codeforces.com/contest/527/problem/C [题意] 让你切割一个长方形; 只能横切或竖切; 让你实时输出切完之后最大的长方形的面积; [题解 ...

  3. Codeforces 527C Glass Carving

    vjudge 上题目链接:Glass Carving 题目大意: 一块 w * h 的玻璃,对其进行 n 次切割,每次切割都是垂直或者水平的,输出每次切割后最大单块玻璃的面积: 用两个 set 存储每 ...

  4. Codeforces 527C Glass Carving(Set)

    意甲冠军  片w*h玻璃  其n斯普利特倍  各事业部为垂直或水平  每个分割窗格区域的最大输出 用两个set存储每次分割的位置   就能够比較方便的把每次分割产生和消失的长宽存下来  每次分割后剩下 ...

  5. 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 ...

  6. 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 ...

  7. Glass Carving CodeForces - 527C (线段树)

    C. Glass Carving time limit per test2 seconds memory limit per test256 megabytes inputstandard input ...

  8. CF #296 (Div. 1) A. Glass Carving 线段树

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

  9. [codeforces 528]B. Clique Problem

    [codeforces 528]B. Clique Problem 试题描述 The clique problem is one of the most well-known NP-complete ...

随机推荐

  1. 每天一个linux命令(11):less 命令

    less 工 具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性. 在 more 的时候,我们并没有办法向前 ...

  2. Daily Scrum – 1/7

    Meeting Minutes 搞定了一个bug,单词面板滚动条的bug: 在电脑屏幕上的屏幕适配有了新思路: Progress   part 组员 今日工作 Time (h) 明日计划 Time ( ...

  3. java中的字符串简介,字符串的优化以及如何高效率的使用字符串

    简介 String最为java中最重要的数据类型.字符串是软件开发中最重要的对象之一,通常,字符串对象在内存中总是占据着最大的空间块.所以,高效处理字符串,将提高系统的整个性能. 在java语言中,S ...

  4. java.lang.NoClassDefFoundError: org/objectweb/asm/Type

    Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/ ...

  5. new-nav-css

    header:before, header:after ,.navigation:before, .navigation:after,.nav-row:before, .nav-row:after,. ...

  6. 关于MyEclipse对Struts2配置文件较检异常 Invalid result location value/parameter

    有时候Struts.xml配置没有错误,完全可以顺利运行,而MyEclipse9以上版本却经常出现一大坨错误标识,错误信息是 Invalid result location value/paramet ...

  7. 【BZOJ-2843&1180】极地旅行社&OTOCI Link-Cut-Tree

    2843: 极地旅行社 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 323  Solved: 218[Submit][Status][Discuss ...

  8. Codeforces Round #342 (Div 2) 解题报告

    除夕夜之有生之年CF第一场 下午从奶奶家回到姥姥家,一看还有些时间,先吃点水果陪姥姥姥爷聊了会儿,再一看表,5:20....woc已经开场20分钟了...于是抓紧时间乱搞.. **A. Guest F ...

  9. BZOJ-4300 绝世好(蛋疼)题 DP(递推)

    翻zky学长的blog时翻出来的..... 4300: 绝世好题 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 736 Solved: 393 [Sub ...

  10. 换了XCode版本之后,iOS应用启动时不占满全屏,上下有黑边

    原因是没有Retina4对应的启动图片,解决方法很简单,就是把Retina4对应的图片给补上就只可以了