【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) (扫描线,平衡树,模拟)
题面
终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物——小蓝的好友。
在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得的暑假。与小蓝不同,小蓝的好友并不想将时间花在旅游上,而是盯上了最近发行的即时战略游戏——SangoCraft。但在前往通关之路的道路上,一个小游戏挡住了小蓝的好友的步伐。
“国家的战争其本质是抢夺资源的战争”是整款游戏的核心理念,这个小游戏也不例外。简单来说,用户需要在给定的长方形土地上选出一块子矩形,而系统随机生成了N个资源点,位于用户所选的长方形土地上的资源点越多,给予用户的奖励也越多。悲剧的是,小蓝的好友虽然拥有着极其优秀的能力,但同时也有着极差的RP,小蓝的好友所选的区域总是没有一个资源点。
终于有一天,小蓝的好友决定投诉这款游戏的制造厂商,为了搜集证据,小蓝的好友想算出至少包含一个资源点的区域的数量。作为小蓝的好友,这自然是你分内之事。
Input
每个输入文件中仅包含一个测试数据。
第一行包含两个由空格隔开的正整数R,C,N,表示游戏在一块[1,R]X[1,C]的地图上生成了N个资源点。
接下来有N行,每行包含两个整数 x,y,表示这个资源点的坐标
(1<=x<=R,1<=Y<=c)。
Output
输出文件应仅包含一个整数,表示至少包含一个资源点的区域的数量。具体的说,设N个资源点的坐标为(i=1…n),你需要计算有多少个四元组(LB,DB,RB,UB)满足1<=LB<=RB<=R,1<=DB<=UB<=C,且存在一个i使得LB<=Xi<=RB,DB<=Yi<=UB均成立。
HINT:资源的位置随机生成
题解
把题目要求转化为总矩形数 - 不包含资源的矩形数。
整个图刷白,把存在z资源的格子染黑(这里把坐标系当成表格,因为题目中其实是允许点和线作为矩形存在的),那么就是求全白子矩形数量。
这是个笛卡尔树或单调栈的经典问题,一般是每行都扫一遍,考虑到这题的数据范围,我们采用扫描线+动态维护。
我们从上往下扫,维护向上的矩形,那么动态维护就只需要支持两种操作:整体向上抬升、单点清零。如果基于笛卡尔树的话,就很方便计算贡献了。于是,我们用 fhq Treap 维护笛卡尔树,整体抬升加个标记就是了,单点清零就把整棵树裂成两半,然后直接加在新点的左右儿子处。由于是随机分布,所以不需要用 heap ,本身笛卡尔树就是平衡的了。
于是这题
O
(
n
log
n
)
O(n\log n)
O(nlogn) 无旋 Treap 解决,常数较大,上百毫秒。
但是考虑到我们最后解出问题的核心,其实利用了随机分布。
如果你在刚想到单调栈后就留意到随机分布会怎样呢?你会想:一个位置往一个方向跳,每次跳到第一个小于等于先前位置的地方,最多会跳 log 次。
于是,除了用 Treap 以外,我们可以直接模拟,维护每个位置往左第一个小于等于他的位置
l
d
ld
ld,以及往右第一个小于等于他的位置
r
d
rd
rd。整体抬升,我们就记录一下当前与底部接壤的矩形个数
x
x
x,抬升时将
x
x
x 加上
(
R
+
1
)
⋅
R
/
2
(R+1)\cdot R/2
(R+1)⋅R/2,并将最终答案加上
x
x
x 。单点清零的时候,我们可以直接跳
l
d
ld
ld 和
r
d
rd
rd 往下,计算清零对
x
x
x 以及最终答案的减少量(由于抬升后假设的是该位置无资源,加点后这个地方是有资源的,因此最终答案也有影响),最重要的是,再顺便把沿途的
l
d
ld
ld、
r
d
rd
rd 更新。你会发现,假使一开始定义的是小于而不是小于等于,那么这步没法做。
于是这题模拟
O
(
n
log
n
)
O(n\log n)
O(nlogn) 做,快如指针,常数极小,几十毫秒。
CODE
几十毫秒的代码
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define SI(x) multiset<x>::iterator
#define MI map<int,int>::iterator
#define PR pair<int,int>
#define BI(x) bitset<x>
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f*x;
}
void putpos(LL x) {
if(!x) return ;
putpos(x/10); putchar('0'+(x%10));
}
void putnum(LL x) {
if(!x) putchar('0');
else if(x < 0) putchar('-'),putpos(-x);
else putpos(x);
}
void AIput(LL x,char c) {putnum(x);putchar(c);}
int n,m,s,o,k;
int R,C;
vector<int> bu[MAXN];
int a[MAXN],ld[MAXN],rd[MAXN],bt;
LL as1,ans;
LL d1(int l,int r,int m,int h) {return (m-l+1) *1ll* (r-m+1) * h;}
void add(int x,int y) {
int yy = a[x];
int ll = x,rr = x,A = ld[x],B = rd[x];
while(yy > y) {
int ny;
if(a[A] >= y) rd[A] = min(rd[A],x);
if(a[B] >= y) ld[B] = max(ld[B],x);
if(a[A] > a[B]) ny = a[A],A = ld[A];
else ny = a[B],B = rd[B];
while(a[ll] > max(y,ny)) ll = ld[ll];
while(a[rr] > max(y,ny)) rr = rd[rr];
int le = yy-max(y,ny);
LL d = d1(ll+1,rr-1,x,le);
as1 -= d; ans -= d;
yy = ny;
}
ld[x] = ll; rd[x] = rr;
a[x] = y;
return ;
}
int main() {
freopen("fish.in","r",stdin);
freopen("fish.out","w",stdout);
R = read();C = read();
n = read();
rd[0] = n+1;ld[R+1] = 0;
a[0] = a[R+1] = -1;
for(int i = 1;i <= R;i ++) {
a[i] = C;
ld[i] = i-1; rd[i] = i+1;
}
for(int i = 1;i <= n;i ++) {
s = read();o = read();
bu[o-1].push_back(s);
}
for(int Y = C-1;Y >= 0;Y --) {
as1 += (R+1)*1ll*R/2ll;
ans += as1;
for(int i = 0;i < (int)bu[Y].size();i ++) {
add(bu[Y][i],Y);
}
}
LL ful = (R+1)*1ll*R/2ll * (C+1)*1ll*C/2ll;
printf("%lld\n",ful-ans);
return 0;
}
【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) (扫描线,平衡树,模拟)的更多相关文章
- bzoj2658: [Zjoi2012]小蓝的好友(mrx)
太神辣 treap的随机键值竟然能派上用场.. 要用不旋转的treap来进行维护区间信息 #include<cstdio> #include<cstring> #include ...
- 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线
[BZOJ2658][Zjoi2012]小蓝的好友(mrx) Description 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的 ...
- @bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)
目录 @description@ @solution@ @accepted code@ @details@ @description@ 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事 ...
- BZOJ2658 ZJOI2012 小蓝的好友(treap)
显然转化为求不包含关键点的矩形个数.考虑暴力,枚举矩形下边界,求出该行每个位置对应的最低障碍点高度,对其建笛卡尔树,答案即为Σhi*(slson+1)*(srson+1),即考虑跨过该位置的矩形个数. ...
- 洛谷 P2611 [ZJOI2012]小蓝的好友 解题报告
P2611 [ZJOI2012]小蓝的好友 题目描述 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小 ...
- [ZJOI2012]小蓝的好友
https://www.luogu.org/problemnew/show/P2611 题解 \(n\times m\)肯定过不去.. 我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵. 然后我们 ...
- YYHS-Super Big Stupid Cross(二分+扫描线+平衡树)
题目描述 “我是超级大沙茶”——Mato_No1 为了证明自己是一个超级大沙茶,Mato 神犇决定展示自己对叉(十字型)有多么的了 解. Mato 神犇有一个平面直角坐标系,上面有一些线段,保证这些线 ...
- P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】
正题 题目链接:https://www.luogu.com.cn/problem/P2611 题目大意 \(r*c\)的网格上有\(n\)个标记点,然后求有多少个矩形包含至少一个标记点. \(1\le ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
随机推荐
- CabloyJS部署了一套演示站点
为了方便大家快速体验和了解CabloyJS的风格和特性,全新部署了一套演示站点.对于初次接触CabloyJS的开发者,不用下载新建项目,就可以直接体验CabloyJS了 在线演示 场景 链接/二维码 ...
- flink-执行模式
flink的执行模式 flink既能处理离线数据,也能处理实时数据,在1.12.0版本以前,批数据返回的数据集合是dataSet,对应一套dataSet的api,从1.12.0版本以后,flink实现 ...
- 【Java集合】ArrayDeque源码解读
简介 双端队列是一种特殊的队列,它的两端都可以进出元素,故而得名双端队列. ArrayDeque是一种以循环数组方式实现的双端队列,它是非线程安全的. 它既可以作为队列也可以作为栈. 继承体系 Arr ...
- WAVE音频格式及及转换代码
音频信号的读写.播放及录音 python已经支持WAV格式的书写,而实时的声音输入输出需要安装pyAudio(http://people.csail.mit.edu/hubert/pyaudio).最 ...
- 倾斜摄影3D模型|手工建模|BIM模型 轻量化处理
一.什么是大场景? 顾名思义,大场景就是能够从一个鸟瞰的角度看到一个大型场景的全貌,比如一个园区.一座城市.一个国家甚至是整个地球.但过去都以图片记录下大场景,如今我们可以通过建造3D模型来还原大场景 ...
- Opentelemetry SDK的简单用法
Opentelemetry SDK的简单用法 概述 Opentelemetry trace的简单架构图如下,客户端和服务端都需要启动一个traceProvider,主要用于将trace数据传输到reg ...
- 【Java面试】Kafka 怎么避免重复消费
Hi,大家好,我是Mic 一个工作5年的粉丝找到我. 他说: "Mic老师,你要是能回答出这个问题,我就佩服你" 我当场就懵了,现在打赌都这么随意了吗? 我问他问题是什么,他说&q ...
- LVGL库入门教程 - 动画
动画可以说是 LVGL 中的特色之一,不过在使用动画前,请确保单片机具有足够的性能来维持足够的帧率. transition:过渡动画 当一个控件的状态发生改变时,可以让样式也发生变化以提醒用户.通过过 ...
- Java 向数组中添加元素
一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路 第一步:把数组转化为集合 list = Arrays.asList(array); 第二步:向集合中添 ...
- Kotlin学习快速入门(7)——扩展的妙用
原文地址: Kotlin学习快速入门(7)--扩展的妙用 - Stars-One的杂货小窝 之前也模模糊糊地在用这个功能,也是十分方便,可以不用继承,快速给某个类增加新的方法,本篇便是来讲解下Kotl ...