bzoj2658: [Zjoi2012]小蓝的好友(mrx)
太神辣 treap的随机键值竟然能派上用场。。
要用不旋转的treap来进行维护区间信息
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream> using namespace std; template<typename Q> Q &read(Q &x) {
static char c, f;
for(f = ; c = getchar(), !isdigit(c); ) if(c == '-') f = ;
for(x = ; isdigit(c); c = getchar()) x = x * + c - '';
if(f) x = -x; return x;
}
template<typename Q> Q read() {
static Q x; read(x); return x;
} typedef long long LL;
const int N = + ; LL S(LL x) {
return x * (x + ) >> ;
} struct Node *null, *pis;
struct Node {
int sz, h, tag;
LL ans;
Node *ch[]; Node() {}
Node(int h) : h(h) {
sz = , ans = tag = ;
ch[] = ch[] = null;
} void add(int d) {
if(this == null) return;
h += d, tag += d;
} void maintain() {
sz = ch[]->sz + ch[]->sz + ;
ans = ;
for(int c = ; c < ; c++) {
ans += ch[c]->ans + S(ch[c]->sz) * (ch[c]->h - h);
}
} void down() {
ch[]->add(tag);
ch[]->add(tag);
tag = ;
} void *operator new(size_t) {
return pis++;
}
}pool[N]; Node *merge(Node *l, Node *r) {
if(l == null) return r;
if(r == null) return l;
if(l->h < r->h) {
l->down();
l->ch[] = merge(l->ch[], r);
return l->maintain(), l;
}else {
r->down();
r->ch[] = merge(l, r->ch[]);
return r->maintain(), r;
}
} typedef pair<Node *, Node *> pnn;
pnn split(Node *o, int k) {
if(o == null) return pnn(null, null);
pnn res; o->down();
if(o->ch[]->sz >= k) {
res = split(o->ch[], k);
o->ch[] = res.second;
res.second = o;
}else {
res = split(o->ch[], k - o->ch[]->sz - );
o->ch[] = res.first;
res.first = o;
}
return o->maintain(), res;
} pair<int, int> p[ + ]; int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif int r, c, n;
scanf("%d%d%d", &r, &c, &n);
for(int i = ; i < n; i++) {
scanf("%d%d", &p[i].first, &p[i].second);
}
sort(p, p + n); pis = pool, null = new Node();
null->sz = ;
Node *root = null;
for(int i = ; i <= c; i++) {
root = merge(root, new Node());
} LL ans = S(r) * S(c);
for(int i = , j = ; i <= r; i++) {
root->add();
while(j < n && p[j].first == i) {
int x = p[j++].second;
pnn r1 = split(root, x - );
pnn r2 = split(r1.second, );
r2.first->h = ;
root = merge(merge(r1.first, r2.first), r2.second);
}
ans -= root->ans + S(root->sz) * root->h;
}
cout << ans << endl; return ;
}
fhq treap
谁说一定要用fhq treap?
用普通的treap就好了 而且常数小!
注意建树最好$O(n)$建一下,每次insert有可能退化成$O(n^2)$的。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream> using namespace std; template<typename Q> Q &read(Q &x) {
static char c, f;
for(f = ; c = getchar(), !isdigit(c); ) if(c == '-') f = ;
for(x = ; isdigit(c); c = getchar()) x = x * + c - '';
if(f) x = -x; return x;
}
template<typename Q> Q read() {
static Q x; read(x); return x;
} typedef long long LL;
const int N = + ; LL S(LL x) {
return x * (x + ) >> ;
} struct Node *null, *pis, *bin[N];
int top;
struct Node {
int sz, v, h, tag;
LL ans;
Node *ch[]; Node() {}
Node(int v, int h) : v(v), h(h) {
sz = , ans = tag = ;
ch[] = ch[] = null;
} void add(int d) {
if(this == null) return;
h += d, tag += d;
} void maintain() {
sz = ch[]->sz + ch[]->sz + ;
ans = ;
for(int c = ; c < ; c++) {
ans += ch[c]->ans + S(ch[c]->sz) * (ch[c]->h - h);
}
} void down() {
ch[]->add(tag);
ch[]->add(tag);
tag = ;
} void *operator new(size_t) {
return top ? bin[--top] : pis++;
} void operator delete(void *p) {
bin[top++] = (Node *) p;
} int cmp(int x) const {
if(x == v) return -;
return x < v ? : ;
}
}pool[N]; void rotate(Node *&o, int d) {
Node *t = o->ch[d];
o->ch[d] = t->ch[d ^ ];
t->ch[d ^ ] = o;
o->maintain();
(o = t)->maintain();
} void modify(Node *&o, int x, int w) {
o->down();
int d = o->cmp(x);
if(d == -) return o->h = w, o->maintain(), void();
modify(o->ch[d], x, w);
if(o->ch[d]->h < o->h) rotate(o, d);
else o->maintain();
} pair<int, int> p[ + ]; void build(Node *&o, int l, int r) {
if(l > r) return;
int mid = (l + r) >> ;
o = new Node(mid, );
build(o->ch[], l, mid - );
build(o->ch[], mid + , r);
o->maintain();
} int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif int r, c, n;
scanf("%d%d%d", &r, &c, &n);
for(int i = ; i < n; i++) {
read(p[i].first), read(p[i].second);
}
sort(p, p + n); pis = pool, null = new Node(, );
null->sz = ;
Node *root;
build(root, , c); LL ans = S(r) * S(c);
for(int i = , j = ; i <= r; i++) {
root->add();
while(j < n && p[j].first == i) {
modify(root, p[j++].second, );
}
ans -= root->ans + S(root->sz) * root->h;
}
cout << ans << endl; return ;
}
普通treap
bzoj2658: [Zjoi2012]小蓝的好友(mrx)的更多相关文章
- 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线
[BZOJ2658][Zjoi2012]小蓝的好友(mrx) Description 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的 ...
- 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) (扫描线,平衡树,模拟)
题面 终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物--小蓝的好友. 在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得 ...
- @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\)肯定过不去.. 我们把给定的点看做障碍点,考虑先补集转化为求全空矩阵. 然后我们 ...
- BZOJ 2658 小蓝的好友
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2658 题意:给出一个n*m的格子.某些格子中有障碍.求包含至少一个障碍的矩形有多少 ...
- P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】
正题 题目链接:https://www.luogu.com.cn/problem/P2611 题目大意 \(r*c\)的网格上有\(n\)个标记点,然后求有多少个矩形包含至少一个标记点. \(1\le ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- HDU 3006 The Number of set(位运算 状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3006 题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14.由给出的集合 ...
- thinkphp关联查询(多表查询)
1.Table方法:定义要操作的数据表名称,可以动态改变当前操作的数据表名称,需要写数据表的全名,包含前缀,可以使用别名, 例如: $Model->Table('think_user user' ...
- ES的安装运行
一.安装,运行 1. 检查java的版本环境 Elasticsearch依赖Java,在书写本文档的时候,推荐使用Oracle JDK 1.8.0_20 或 1.7.0_55以后的版本. 在安装Ela ...
- Fedora 21 中添加及更新源的命令
原文: Fedora 21 中添加及更新源的命令 fedora的软件源信息文件(*.repo)都是放在 /etc/yum.repos.d 目录下的.可以通过# ls -l /etc/yum.repos ...
- JavaScript学习总结【3】、JS对象
在 JS 中一切皆对象,并提供了多个内置对象,比如:String.Array.Date 等,此外还支持自定义对象.对象只是一种特殊类型的数据,并拥有属性和方法,属性是与对象相关的值,方法是能够在对象上 ...
- laravel学习:修改时区
config/app.php 'timezone' => 'UTC', 改为 'timezone' => 'PRC',
- node 后台ajax文件(同时支持http、https)
var http = require("http"), Url = require("url"), querystring = require('queryst ...
- Hadoop, Python, and NoSQL lead the pack for big data jobs
Hadoop, Python, and NoSQL lead the pack for big data jobs Rise in cloud-based analytics could incr ...
- shell编程的一些例子1
1.$0-$9及$# $@的使用 demo_arg 内容 #!/bin/bash echo "程序名:$0" echo "命令传递参数个数:$#" echo & ...
- Java 高效检查一个数组中是否包含某个值
如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ...