[codeforces 528]A. Glass Carving
[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.
输出
输入示例
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的更多相关文章
- codeforces 527 C Glass Carving
Glass Carving time limit per test 2 seconds Leonid wants to become a glass carver (the person who cr ...
- 【codeforces 527C】Glass Carving
[题目链接]:http://codeforces.com/contest/527/problem/C [题意] 让你切割一个长方形; 只能横切或竖切; 让你实时输出切完之后最大的长方形的面积; [题解 ...
- Codeforces 527C Glass Carving
vjudge 上题目链接:Glass Carving 题目大意: 一块 w * h 的玻璃,对其进行 n 次切割,每次切割都是垂直或者水平的,输出每次切割后最大单块玻璃的面积: 用两个 set 存储每 ...
- Codeforces 527C Glass Carving(Set)
意甲冠军 片w*h玻璃 其n斯普利特倍 各事业部为垂直或水平 每个分割窗格区域的最大输出 用两个set存储每次分割的位置 就能够比較方便的把每次分割产生和消失的长宽存下来 每次分割后剩下 ...
- 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 ...
- 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 ...
- Glass Carving CodeForces - 527C (线段树)
C. Glass Carving time limit per test2 seconds memory limit per test256 megabytes inputstandard input ...
- 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 ...
- [codeforces 528]B. Clique Problem
[codeforces 528]B. Clique Problem 试题描述 The clique problem is one of the most well-known NP-complete ...
随机推荐
- jQuery问题:$XXX is not a function
用火狐浏览器打开,js代码一段不执行,F12以后看见下面的错误: 网上查看说是jQuery文件引用的问题,把jQuery.js引入语句修改了一下,果然没有错了. 我原来的引用语句是:<scrip ...
- 小记:Quartz StartNow() 无效
今天遇到一个问题,调度器在启动时无法立刻开始执行任务,代码如下: var trigger = TriggerBuilder.Create() .StartNow() //此处无效 .WithCronS ...
- “耐撕”团队2016.04.19站立会议
1. 时间 : 20:20--20:40 共计20分钟 2. 人员 : Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客 ...
- easyui中tree控件添加自定义图标icon
来源于:http://blog.163.com/lintianhuanhai@126/blog/static/165587366201421704420256/ <!DOCTYPE html&g ...
- 传智168期JavaEE就业班 day03-js
* 课程回顾: * CSS * CSS的简介 * 层叠样式表. * CSS与HTML的结合(4种) * HTML的标签提供了属性 style="CSS的代码" * HTML提供了标 ...
- iOS边练边学--NSURLSession、NSURLSessionTask的介绍与使用以及url中包含了中文的处理方法
一.NSURLSession.NSURLSessionTask的使用步骤 首先创建NSURLSession对象 通过NSURLSession对象创建对应的任务 <1>NSURLSessio ...
- BZOJ-1015 StarWar星球大战 并查集+离线处理
1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec Memory Limit: 162 MB Submit: 4105 Solved: 1826 [Submit ...
- 洛谷P1656 炸铁路
题目描述 因为某国被某红色政权残酷的高压暴力统治.美国派出将军uim,对该国进行战略性措施,以解救涂炭的生灵. 该国有n个城市,这些城市以铁路相连.任意两个城市都可以通过铁路直接或者间接到达. uim ...
- Yii2 初体验
看着Yii1.1有那么多的不爽,又看着Yii2一天天成熟起来,于是凑一个小项目的原型阶段,试着用Yii2搞一搞. 随手写了一点体会,以一个Yii1的熟练工人看向Yii2的视角,简单一说吧.(将来随时可 ...
- Kd-tree算法原理
参考资料: Kd Tree算法原理 Kd-Tree,即K-dimensional tree,是一棵二叉树,树中存储的是一些K维数据.在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成 ...