@bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)
@description@
终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物——小蓝的好友。
在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得的暑假。与小蓝不同,小蓝的好友并不想将时间花在旅游上,而是盯上了最近发行的即时战略游戏——SangoCraft。但在前往通关之路的道路上,一个小游戏挡住了小蓝的好友的步伐。
“国家的战争其本质是抢夺资源的战争”是整款游戏的核心理念,这个小游戏也不例外。简单来说,用户需要在给定的长方形土地上选出一块子矩形,而系统随机生成了N个资源点,位于用户所选的长方形土地上的资源点越多,给予用户的奖励也越多。悲剧的是,小蓝的好友虽然拥有着极其优秀的能力,但同时也有着极差的RP,小蓝的好友所选的区域总是没有一个资源点。
终于有一天,小蓝的好友决定投诉这款游戏的制造厂商,为了搜集证据,小蓝的好友想算出至少包含一个资源点的区域的数量。作为小蓝的好友,这自然是你分内之事。
@solution@
简单容斥转成求不包含任何资源点的区域数量。
这个经典问题做法很多,但必须要利用题设(随机,资源点个数少)才能得到合理的时间复杂度。
考虑一种基于笛卡尔树的做法:枚举最下面的一行,计算每一列往上最长延伸的长度 len,以长度为关键字从小到大建立笛卡尔树。
这样一来笛卡尔树中每个点的贡献为 (len[x] - len[fa]) * (siz[x] * (siz[x] + 1) / 2),答案为贡献之和。
因为笛卡尔树本质就是 treap,所以可以从上往下扫描的同时用 treap 维护出笛卡尔树及其对应的信息即可。
因为点随机,所以笛卡尔树(treap)的期望高度为 O(log),因此就可以 O(nlog n) 通过该题。
@accepted code@
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
#define mp make_pair
#define fi first
#define se second
const int MAXN = 40000;
struct treap{
struct node{
ll sum, val;
int pri, key, tag, siz;
node *ch[2], *fa;
}pl[MAXN + 5], *NIL, *ncnt;
typedef pair<node*, node*> Droot;
treap() {
NIL = ncnt = pl;
NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL;
NIL->key = NIL->pri = NIL->tag = NIL->siz = 0, NIL->sum = NIL->val = 0;
}
node *newnode(int k) {
node *p = (++ncnt);
p->ch[0] = p->ch[1] = p->fa = NIL;
p->key = k, p->siz = 1, p->tag = p->pri = 0, p->sum = p->val = 0;
return p;
}
void pushup(node *x) {
x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
x->val = 1LL * x->siz * (x->siz + 1) * (x->pri - x->fa->pri) / 2;
x->sum = x->ch[0]->sum + x->ch[1]->sum + x->val;
}
void maintain(node *x, int k) {
if( x != NIL ) x->tag += k, x->pri += k, pushup(x);
}
void pushdown(node *x) {
if( x->tag ) {
maintain(x->ch[0], x->tag);
maintain(x->ch[1], x->tag);
x->tag = 0;
}
}
void set_child(node *x, node *y, int d) {
if( y != NIL ) y->fa = x, pushup(y);
if( x != NIL ) x->ch[d] = y, pushup(x);
}
node *merge(node *x, node *y) {
if( x == NIL ) return y;
if( y == NIL ) return x;
if( x->pri < y->pri ) {
pushdown(x), x->ch[1]->fa = NIL;
set_child(x, merge(x->ch[1], y), 1);
return x;
}
else {
pushdown(y), y->ch[0]->fa = NIL;
set_child(y, merge(x, y->ch[0]), 0);
return y;
}
}
Droot split(node *x, int k) {
if( x == NIL ) return mp(NIL, NIL);
pushdown(x);
if( x->key <= k ) {
x->ch[1]->fa = NIL; Droot p = split(x->ch[1], k);
set_child(x, p.fi, 1); return mp(x, p.se);
}
else {
x->ch[0]->fa = NIL; Droot p = split(x->ch[0], k);
set_child(x, p.se, 0); return mp(p.fi, x);
}
}// key <= k ; key > k
node *modify(node *rt, int k) {
Droot p = split(rt, k), q = split(p.fi, k - 1);
q.se->pri = 0, pushup(q.se);
return merge(merge(q.fi, q.se), p.se);
}
}T;
typedef pair<treap::node*, treap::node*> Droot;
/*
(pri[x] - pri[fa[x]]) * (siz[x]*siz[x] + siz[x]) / 2
*/
vector<int>v[MAXN + 5];
treap::node *nd[MAXN + 5], *rt;
treap::node *build(int l, int r) {
if( l > r ) return T.NIL;
int m = (l + r) >> 1; nd[m] = T.newnode(m);
T.set_child(nd[m], build(l, m - 1), 0);
T.set_child(nd[m], build(m + 1, r), 1);
return nd[m];
}
int main() {
int R, C, N; scanf("%d%d%d", &R, &C, &N), rt = build(1, C);
for(int i=1;i<=N;i++) {
int x, y; scanf("%d%d", &x, &y);
v[x].push_back(y);
}
ll ans = 1LL*R*(R + 1)/2*C*(C + 1)/2;
for(int i=1;i<=R;i++) {
T.maintain(rt, 1);
for(int j=0;j<v[i].size();j++)
rt = T.modify(rt, v[i][j]);
ans -= rt->sum;
}
printf("%lld\n", ans);
}
@details@
记得开 long long。
一看才发现是 ZJOI2012 的题,发现一道 8 年前的题就让我自闭了,深深感到自己的弱。
@bzoj - 2658@ [Zjoi2012]小蓝的好友(mrx)的更多相关文章
- 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线
[BZOJ2658][Zjoi2012]小蓝的好友(mrx) Description 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的 ...
- 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) (扫描线,平衡树,模拟)
题面 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得 ...
- bzoj2658: [Zjoi2012]小蓝的好友(mrx)
太神辣 treap的随机键值竟然能派上用场.. 要用不旋转的treap来进行维护区间信息 #include<cstdio> #include<cstring> #include ...
- 洛谷 P2611 [ZJOI2012]小蓝的好友 解题报告
P2611 [ZJOI2012]小蓝的好友 题目描述 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小 ...
- BZOJ2658 ZJOI2012 小蓝的好友(treap)
显然转化为求不包含关键点的矩形个数.考虑暴力,枚举矩形下边界,求出该行每个位置对应的最低障碍点高度,对其建笛卡尔树,答案即为Σhi*(slson+1)*(srson+1),即考虑跨过该位置的矩形个数. ...
- [ZJOI2012]小蓝的好友
https://www.luogu.org/problemnew/show/P2611 题解 \(n\times m\)肯定过不去.. 我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵. 然后我们 ...
- bzoj 2656 [Zjoi2012]数列(sequence) 递推+高精度
2656: [Zjoi2012]数列(sequence) Time Limit: 2 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Descri ...
- BZOJ 2658 小蓝的好友
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658 题意:给出一个n*m的格子.某些格子中有障碍.求包含至少一个障碍的矩形有多少 ...
- bzoj 2815 [ZJOI2012]灾难(构造,树形DP)
[题意] 求把每个点删除后,不可达点的数目. [思路] 构造一棵“灭绝树”,要求这棵树满足如果删除根节点后则该子树内的所有结点都不可达.则答案为子树大小-1. 如何构造这棵“灭绝树”? 将原图拓扑排序 ...
随机推荐
- 英语四六级模拟考试系统APP
Android studio开发的.eclipse的SSM框架作为服务器后台.Mysql5.6. 我先上几张图吧. 需要源码可以留言给我.另外本人接外包或者有问题也可以问我.留言,我会看的.
- 王艳 201771010127《面向对象程序设计(java)》第十六周学习总结
一:理论部分 1.程序:是一段静态的代码,它是应用程序执行的蓝本. 2.进程:是程序的一次动态执行,它对应了从代码加载.执行至执行完毕的一个完整过程. 3.多线程:是进程执行过程中产生的多条执行线索. ...
- Poj1753 翻转棋子
这个题就是用枚举举遍所有情况,然后一个一个深搜看看是不是符合条件,符合条件直接退出,不符合则继续, 由于表格只有16个所以可以得知最多的步数只能是16,所以可以根据步数从0到16依次枚举, 第一个符合 ...
- ShoneSharp语言(S#)的设计和使用介绍系列(11)—“类”披炫服靓妆化成“表”
ShoneSharp语言(S#)的设计和使用介绍 系列(11)—“类”披炫服靓妆化成“表” 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/Sh ...
- Python-pygame案例小飞机
import pygame, sys from pygame.locals import * import random '''飞机躲避导弹''' # 玩家 class Player(pygame.s ...
- [PHP学习教程 - 网络]002.$_SERVER["SCRIPT_NAME"]、$_SERVER["PHP_SELF"]、$_SERVER["QUERY_STRING"]、$_SERVER["REQUEST_URI"]介绍($_SERVER URL Infomation)
引言:在使用原生PHP的时候,对于URL路径的切割,如:域名,查询参数等等的提取,通常绝大多数兄弟会忽略$_SERVER中定义的内置常量的关系,这里为大家讲解一下. 常用的URL请求路径$_SERVE ...
- Linux、Ubuntu、CentOS安装和配置zsh
目录 01 zsh的安装 02 配置zsh 2.1 安装oh-my-zsh 2.2 查看oh-my-zsh目录 2.3 oh-my-zsh 插件的管理 2.3.1 添加插件 2.3.2 zsh-aut ...
- python异常1
异常的层次结构: BaseException [所有异常的基类] +-- SystemExit [解释器请求退出] +-- KeyboardInterrupt [用户中断执行(通常是输入^C)] +- ...
- harbor越权漏洞(CVE-2019-16097)
漏洞介绍 这个漏洞可以在注册发送post包时,加入has_admin_role:true就可以直接注册成为管理员,下图可以看看user的结构: 有很多属性,此处我们关注的是"HasAdmin ...
- Java并发编程 (十) 多线程并发拓展
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.死锁 1.死锁的定义 所谓的死锁是指两个或两个以上的线程在等待执行的过程中,因为竞争资源而造成的一种 ...