http://codeforces.com/problemset/problem/527/C

这题总体思路就是,每画一条线,然后就找到x间距的最max值和y间距的最max值,相乘就是当前的ans

那么我需要维护这样的一个数列,每次往里面添加一个元素,然后查询相邻两个元素的差值的最大值。

倒着做比较简单,首先把所有元素插上去,然后最大值直接暴力算一次。然后后来只有删除操作,这个操作只会让最大值变大。

每次删除后,检查上面和下面的新间距,和最大值比较一下就好。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
set<int> ss[];
LL ans[ + ];
struct Node {
char op;
int val;
}node[ + ];
void fuck(int id) {
if (node[id].op == 'H') {
ss[].erase(node[id].val);
} else ss[].erase(node[id].val);
}
void work() {
int w, h, n;
cin >> w >> h >> n;
ss[].insert(); ss[].insert(w);
ss[].insert(); ss[].insert(h);
set<int> :: iterator it1, it2;
for (int i = ; i <= n; ++i) {
char str[];
int val, flag = false;
scanf("%s%d", str, &val);
if (str[] == 'H') {
ss[].insert(val);
} else ss[].insert(val);
node[i].op = str[];
node[i].val = val;
}
int mx1 = ; // v
it2 = ss[].begin();
it2++;
for (it1 = ss[].begin(); it2 != ss[].end(); ++it2, ++it1) {
mx1 = max(mx1, *it2 - *it1);
}
int mx2 = -inf;
it2 = ss[].begin();
it2++;
for (it1 = ss[].begin(); it2 != ss[].end(); ++it2, ++it1) {
mx2 = max(mx2, *it2 - *it1);
}
ans[n] = 1LL * mx1 * mx2;
// cout << mx1 << " " << mx2 << endl;
fuck(n);
mx1 = ; // v
it2 = ss[].begin();
it2++;
for (it1 = ss[].begin(); it2 != ss[].end(); ++it2, ++it1) {
mx1 = max(mx1, *it2 - *it1);
}
mx2 = ;
it2 = ss[].begin();
it2++;
for (it1 = ss[].begin(); it2 != ss[].end(); ++it2, ++it1) {
mx2 = max(mx2, *it2 - *it1);
}
for (int i = n - ; i >= ; --i) {
if (node[i].op == 'H') {
it1 = ss[].lower_bound(node[i].val);
it2 = it1;
it2++;
mx2 = max(mx2, *it2 - *it1);
it2 = it1;
it1--;
mx2 = max(mx2, *it2 - *it1);
it1++;
} else {
it1 = ss[].lower_bound(node[i].val);
it2 = it1;
it2++;
mx1 = max(mx1, *it2 - *it1);
it2 = it1;
it1--;
mx1 = max(mx1, *it2 - *it1);
it1++;
}
it2 = it1;
it2++;
it1--;
fuck(i);
ans[i] = 1LL * mx1 * mx2;
if (node[i].op == 'H') {
mx2 = max(mx2, *it2 - *it1);
} else mx1 = max(mx1, *it2 - *it1);
}
for (int i = ; i <= n; ++i) {
cout << ans[i] << endl;
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

写的很乱,因为是绝杀的。

正着也可以。

用一个multiset来维护当前拥有的差值,一开始是h

然后每添加一条边,可以找出在原数组中的上界和下界,这个差值是要删除的那个差值,然后添加新差值即可。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
set<int> x, y;
multiset<int> xx, yy;
void work() {
int w, h, n;
cin >> w >> h >> n;
x.insert(), x.insert(w);
y.insert(), y.insert(h);
xx.insert(w), yy.insert(h);
for (int i = ; i <= n; ++i) {
char str[];
int pos;
cin >> str >> pos;
if (str[] == 'H') {
auto it1 = y.lower_bound(pos);
int d1 = *it1;
it1--;
int d2 = *it1;
auto del = yy.lower_bound(d1 - d2);
yy.erase(del);
yy.insert(d1 - pos);
yy.insert(pos - d2);
y.insert(pos);
} else {
auto it1 = x.lower_bound(pos);
int d1 = *it1;
it1--;
int d2 = *it1;
auto del = xx.lower_bound(d1 - d2);
xx.erase(del);
xx.insert(d1 - pos);
xx.insert(pos - d2);
x.insert(pos);
}
auto itx = xx.rbegin(), ity = yy.rbegin();
cout << 1LL * (*itx) * (*ity) << endl;
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
IOS;
work();
return ;
}

C. Glass Carving 正着做或者倒着做都可以的更多相关文章

  1. Codeforces 527C Glass Carving

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

  2. C. Glass Carving (CF Round #296 (Div. 2) STL--set的运用 &amp;&amp; 并查集方法)

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

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

  4. [codeforces 528]A. Glass Carving

    [codeforces 528]A. Glass Carving 试题描述 Leonid wants to become a glass carver (the person who creates ...

  5. Codeforces 527C Glass Carving(Set)

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

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

  7. 【CF527C】Glass Carving

    [CF527C]Glass Carving 题面 洛谷 题解 因为横着切与纵切无关 所以开\(set\)维护横着的最大值和纵着的最大值即可 #include <iostream> #inc ...

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

  9. CF # 296 C Glass Carving (并查集 或者 multiset)

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

随机推荐

  1. Docker容器里的进程为什么要前台运行

    <第一本Docker书>里面,讲到Docker容器启动web服务时,都指定了前台运行的参数,例如apache: ENTRYPOINT [ "/usr/sbin/apache2&q ...

  2. Git 权限控制

    除了 Git 命令,权限控制也是 Git 中极为重要的组成部分,本文主要介绍 GitLab 系统提供的最常用的权限控制功能. 一.分配成员角色 首先来了解下,Git 中的五种角色: 每一种角色所拥有的 ...

  3. HDOJ1548(DFS超内存,BFS过了)

    DFS代码 #include<iostream> #include<cstdio> using namespace std; #define Min(a,b) (a<b) ...

  4. web攻击之二:CSRF跨站域请求伪造

    CSRF是什么? (Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为“One Click ...

  5. get and set

    (function () { function Student(name, age, gender) { this._name = name; this._age = age; this._gende ...

  6. content-disposition attachment filename 在Firefox和IE中得到不同的结果

    在Firefox中需要把filename 用双引号包起来,才能得到想要的名字,不然如果含有空格,会丢掉空格后面的部分.而IE会把空格转为_,因此也需要HttpUtility.UrlPathEncode ...

  7. Java探索之旅(2)——GUI输入输出与代码的规范性

    1.知识点概叙 ① 定名常量:关键字final,类似C++ const定义,一般用大写:final double PI=3.1415926 ② 5/2=2:5.0/2=2.5://通常意义的除法,至少 ...

  8. npm设置代理提高下载速度

    *nix上给网络类程序设置代理的通用办法,即导出http_proxy/https_proxy环境变量对npm不起作用 需要用npm自己的配置命令来解决: npm set proxy $PROXY np ...

  9. Java虚拟机内存配置

    在做java开发时尤其是大型软件开发时经常会遇到内存溢出的问题,比如说OutOfMemoryError等.这是个让开发人员很痛苦.也很纠结的问题,因为我们有时不知道什么样的操作导致了这种问题的发生.所 ...

  10. jQuery学习1

    学习jQuery的过程中发现了一个博客把jquery的要点整理的很不错,摘抄其精华以备学习.感谢:http://blog.csdn.net/wph_1129/article/details/59932 ...