题意:

一开始有n个非负整数h[i],接下来会进行m次操作,第i次会给出一个数c[i],要求选出c[i]个大于0的数并将它们-1,问最多可以进行多少次?

分析:

首先一个显然的贪心就是每次都将最大的c[i]个数-1,于是就可以用无旋式treap来维护,基本操作中split_k和split_v都使用普通的merge,但在提取区间并打完标记后,因为整个序列的单调性发生改变,需要使用启发式合并(只在修改过后使用)。

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<ctime>
#include<queue>
using namespace std;
template<typename T>
inline void read(T &x) {
T i = 0, f = 1;
char ch = getchar();
for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
if(ch == '-') f = -1, ch = getchar();
for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
x = i * f;
}
template<typename T>
inline void wr(T x) {
if(x < 0) putchar('-'), x = -x;
if(x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
const int N = 1e6 + 50, OO = 0x3f3f3f3f;
int n, m, h[N], c[N];
inline int Rand(){
static int RAND_VAL = 1388593021;
return RAND_VAL += RAND_VAL << 2 | 1;
}
#define SZ(x) (x?x->sze:0)
#define V(x) (x?x->val:OO)
struct node{
node *lc, *rc;
int sze, pri, val, tag;
node():lc(NULL), rc(NULL){}
inline void add(int v){
val += v, tag += v;
}
inline void pushDown(){
if(tag != 0){
if(lc) lc->add(tag);
if(rc) rc->add(tag);
tag = 0;
}
}
inline node* upt(){
sze = SZ(lc) + SZ(rc) + 1;
return this;
}
inline void print(){
pushDown();
if(lc) lc->print();
cout<< val<<" ";
if(rc) rc->print();
}
}pool[N], *tail = pool, *rt = NULL;
inline node* newNode(int v){
node *x = tail++;
x->val = v;
x->lc = x->rc = NULL;
x->pri = Rand();
x->tag = 0;
x->sze = 1;
return x;
}
inline node* Merge_o(node *x, node *y){
if(!x) return y;
if(!y) return x;
node *L, *R;
if(x->pri < y->pri){
x->pushDown();
x->rc = Merge_o(x->rc, y);
return x->upt();
}
else {
y->pushDown();
y->lc = Merge_o(x, y->lc);
return y->upt();
}
}
inline void Split_v(node *x, int v, node *&L, node *&R);
inline node* Merge(node *x, node *y){
if(!x) return y;
if(!y) return x;
x->pushDown(), y->pushDown();
if(x->pri > y->pri) swap(x, y);
node *L, *R;
Split_v(y, x->val, L, R);
x->lc = Merge(x->lc, L);
x->rc = Merge(x->rc, R);
x->upt();
return x;
}
inline void Split_k(node *x, int k, node *&L, node *&R){
if(x == NULL){L = NULL, R = NULL; return;}
x->pushDown();
if(SZ(x->lc) < k){
Split_k(x->rc, k - SZ(x->lc) - 1, L, R);
x->rc = NULL; x->upt();
L = Merge_o(x, L);
}
else{
Split_k(x->lc, k, L, R);
x->lc = NULL; x->upt();
R = Merge_o(R, x);
}
}
inline void Split_v(node *x, int v, node *&L, node *&R){
if(x == NULL){L = NULL, R = NULL; return;}
x->pushDown();
if(V(x) <= v){
Split_v(x->rc, v, L, R);
x->rc = NULL; x->upt();
L = Merge_o(x, L);
}
else{
Split_v(x->lc, v, L, R);
x->lc = NULL, x->upt();
R = Merge_o(R, x);
}
}
inline node* build(){
static node* stk[N];
node* pre;
int top = 0;
for(register int i = 1; i <= n; i++){
node *x = newNode(h[i]);
pre = NULL;
while(top && stk[top]->pri > x->pri)
pre = stk[top]->upt(), stk[top--] = NULL;
if(stk[top]) stk[top]->rc = x;
x->lc = pre; stk[++top] = x;
}
while(top) stk[top--]->upt();
return stk[1];
}
int main(){
freopen("h.in", "r", stdin);
read(n), read(m);
for(register int i = 1; i <= n; i++) read(h[i]);
for(register int i = 1; i <= m; i++) read(c[i]);
sort(h + 1, h + n + 1);
rt = build();
for(register int i = 1; i <= m; i++){
if(!c[i]) continue;
if(c[i] > n){
wr(i - 1);
return 0;
}
node *L, *R, *p, *q;
Split_v(rt, 0, L, R);
if(SZ(R) >= c[i]){
Split_k(R, SZ(R) - c[i], p, q);
if(q) q->add(-1);
R = Merge(p, q);
}
else{
wr(i - 1);
return 0;
}
rt = Merge(L, R);
}
wr(m);
return 0;
}

NOIP 模拟 序列操作 - 无旋treap的更多相关文章

  1. 【算法学习】Fhq-Treap(无旋Treap)

    Treap——大名鼎鼎的随机二叉查找树,以优异的性能和简单的实现在OIer们中广泛流传. 这篇blog介绍一种不需要旋转操作来维护的Treap,即无旋Treap,也称Fhq-Treap. 它的巧妙之处 ...

  2. 【序列操作V】平衡树(无旋treap)

    题目描述 维护一个队列,初始为空.依次加入 n(1≤n≤105)个数 ai(-109≤ai≤109),第 i(1≤i≤n)个数加入到当前序列第 bi(0≤bi≤当前序列长度)个数后面.输出最终队列. ...

  3. 无旋treap的区间操作实现

    最近真的不爽...一道维修数列就做了我1上午+下午1h+1晚上+晚上1h+上午2h... 一道不错的自虐题... 由于这一片主要讲思想,代码我放这里了 不会无旋treap的童鞋可以进这里 呵呵... ...

  4. [转载]无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )

    转自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182631.html 1500: [NOI2005]维修数列 Time Limit: 10 Sec  Mem ...

  5. [BZOJ3223]文艺平衡树 无旋Treap

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个 ...

  6. [您有新的未分配科技点] 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Description Input 输入的第1 行包含两个数N 和M(M ≤20 ...

  7. 无旋treap大法好

    无旋Treap大法好 原理? 是一棵二叉查找树: 一个节点左子树权值都比他小,右子树权值都比他大 所以可以维护序列(以位置为权值),或数值(以数值为权值) 是一个堆: 每个节点除了上述提到的权值外,还 ...

  8. 模板 - 数据结构 - 可持久化无旋Treap/PersistentFHQTreap

    有可能当树中有键值相同的节点时,貌似是要对Split和Merge均进行复制的,本人实测:只在Split的时候复制得到了一个WA,但只在Merge的时候复制还是AC,可能是恰好又躲过去了.有人说假如确保 ...

  9. BZOJ3678 wangxz与OJ (平衡树 无旋treap)

    题面 维护一个序列,支持以下操作: 1.在某个位置插入一段值连续的数. 2.删除在当前序列位置连续的一段数. 3.查询某个位置的数是多少. 题解 显然平衡树,一个点维护一段值连续的数,如果插入或者删除 ...

随机推荐

  1. ArcGIS 10 影像、栅格数据格式批量转换

    转自原文 ArcGIS 10 影像.栅格数据格式批量转换 在做三维场景的时候,经常会涉及多种不同格式DEM数据或者影像的转换,如ASCII.GRID.IMG.TIFF等等,遇到大数据量时,我们就需要批 ...

  2. 文字记录而已!!人民币直充/兑换PayPal美金

    人民币直充/兑换PayPal美金 用PAYPAL国际使用外国货币,没有信用卡是不能冲值的,到淘宝买吧,被骗的几率大一些,弄来弄去,PAYPAL被冻结. 今天朋友介绍使用 中美互动网 让它给自己的PAY ...

  3. bootstrap课程12 滚动监听如何实现(bootstrap方式和自定义方式)

    bootstrap课程12 滚动监听如何实现(bootstrap方式和自定义方式) 一.总结 一句话总结:通过监听滚动的高,判断滚动的高是否大于元素距离顶端的距离 1.如何知道屏幕滚动的高? st=$ ...

  4. 微信消息体加解密及EncodingAESKey

    公众平台消息体签名及加解密方案概述 1.新增消息体签名验证,用于公众平台和公众账号验证消息体的正确性 2.针对推送给微信公众账号的普通消息和事件消息,以及推送给设备公众账号的设备消息进行加密 3.公众 ...

  5. 【例题 7-7 UVA - 1354】Mobile Computing

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 秤砣都是在叶子节点. 可以把它看成一个二叉树. 则我们每次只需要选择任意两个"节点",让他们组成一棵二叉树就可以 ...

  6. 接口如何使用(以笑话大全api为例)

    接口如何使用(以笑话大全api为例) 一.总结 一句话总结:直接用ajax,或者post,get方式向接口网址请求数据,然后接收网站传过来的数据就好,和我们写网站的时候前台向后台请求数据的方式一样. ...

  7. amazeui学习笔记--css(基本样式2)--基础设置Base

    amazeui学习笔记--css(基本样式2)--基础设置Base 一.总结 1.盒子模型:外margin,内padding,这里的内外指的边框 2.border-box:Amaze UI 将所有元素 ...

  8. JS面向对象程序设计(OOP:Object Oriented Programming)

    你是如何理解编程语言中的面向对象的? 我们研究JS和使用JS编程本身就是基于面向对象的思想来开发的,JS中的一切内容都可以统称为要研究的“对象”,我们按照功能特点把所有内容划分成“几个大类,还可以基于 ...

  9. 小米R2D samba共享配置

    编辑samba配置文件 vi /etc/config/samba 需要注意的是,samba有自己的配置文件 /etc/samba/smb.conf,但是修改这个文件是不生效的,这个配置文件会在重启路由 ...

  10. 【习题 5-2 UVA-1594】Ducci Sequence

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] map加vector轻松搞定. [代码] #include <bits/stdc++.h> using namespac ...