文章目录

  • Running Median
  • Sequence
  • Buy Low Sell High
  • [APIO/CTSC 2007] 数据备份
  • [NOI2010] 超级钢琴
  • 「LibreOJ β Round」ZQC 的手办

Running Median

source

对顶栈

用大根堆和小根堆一起维护

  • 若元素小于等于大根堆栈顶,放入大根堆
  • 否则放入小根堆

大根堆维护的就是前一半较小的树,小根堆维护的就是后一半较大的树

最后调整两个堆的大小(大根堆比小根堆多一)

答案就是大根堆的栈顶

#include <cstdio>
#include <queue>
using namespace std;
#define maxn 10000
priority_queue < int > MS;
priority_queue < int, vector < int >, greater < int > > IS;
int x[maxn];int main() {int T, Case, n;scanf( "%d", &T );while( T -- ) {while( ! MS.empty() ) MS.pop();while( ! IS.empty() ) IS.pop();scanf( "%d %d", &Case, &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &x[i] );int cnt = 0;printf( "%d %d\n", Case, ( n + 1 ) >> 1 );for( int i = 1;i <= n;i ++ ) {if( MS.empty() || x[i] < MS.top() ) MS.push( x[i] );else IS.push( x[i] );if( i & 1 ) {while( IS.size() < ( i >> 1 ) )IS.push( MS.top() ), MS.pop();while( MS.size() < ( ( i + 1 ) >> 1 ) )MS.push( IS.top() ), IS.pop();cnt ++, printf( "%d ", MS.top() );if( cnt == 10 ) printf( "\n"), cnt = 0;}}printf( "\n" );}return 0;
}

Sequence

source

先把每行的mmm个元素排序

一层一层的往下叠加,仅保留前mmm小即可

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 2005
priority_queue < int > q;
int T, n, m;
int now[maxn], nxt[maxn];int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d", &n, &m );for( int i = 1;i <= m;i ++ )scanf( "%d", &now[i] );sort( now + 1, now + m + 1 );for( int k = 1;k < n;k ++ ) {for( int i = 1;i <= m;i ++ )scanf( "%d", &nxt[i] );sort( nxt + 1, nxt + m + 1 );for( int i = 1;i <= m;i ++ )for( int j = 1;j <= m;j ++ ) {int val = now[i] + nxt[j];if( q.size() == m && ! q.empty() && val >= q.top() ) break;else {q.push( val );while( q.size() > m ) q.pop();}}for( int i = 1;i <= m;i ++ )now[m - i + 1] = q.top(), q.pop();}for( int i = 1;i <= m;i ++ )printf( "%d ", now[i] );printf( "\n" );}return 0;
}

Buy Low Sell High

source

反悔贪心

如果第iii天的收益更好,那么弹出栈顶,选择第iii天

e.g.

k→j→ik\rightarrow j\rightarrow ik→j→i,最优选择为k→ik\rightarrow ik→i

在当前最优解的jjj时,选择k→jk\rightarrow jk→j先记录临时答案,然后把jjj的股票价放进栈

在iii的时候进行pi−pjp_i-p_jpi​−pj​,刚好抵消 pj−pk+pi−pj=pi−pkp_j-p_k+p_i-p_j=p_i-p_kpj​−pk​+pi​−pj​=pi​−pk​

#include <cstdio>
#include <queue>
using namespace std;
#define int long long
#define maxn 300005
priority_queue < int, vector < int >, greater < int > > q;
int n, ans;
int p[maxn];signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ )scanf( "%lld", &p[i] );for( int i = 1;i <= n;i ++ ) {if( ! q.empty() && q.top() < p[i] )ans += p[i] - q.top(), q.pop(), q.push( p[i] );q.push( p[i] );}printf( "%lld\n", ans );return 0;
}

[APIO/CTSC 2007] 数据备份

source

反悔贪心

选了iii就不能选i−1,i+1i-1,i+1i−1,i+1

弥补的代价为di−1+di+1−did_{i-1}+d_{i+1}-d_idi−1​+di+1​−di​

双向链表维护

#include <queue>
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100005
#define int long long
struct node {int id, l, r, val;node(){}node( int ID, int L, int R, int Val ) {id = ID, l = L, r = R, val = Val;}
}it[maxn];
struct Node {int id, val;Node(){}Node( int ID, int Val ) {id = ID, val = Val;}bool operator < ( Node t ) const {return val > t.val;}
};
priority_queue < Node > q;
int n, k, ans;
bool vis[maxn];void Delete( int x ) {it[x].l = it[it[x].l].l;it[x].r = it[it[x].r].r;it[it[x].l].r = x;it[it[x].r].l = x;
}signed main() {int last;scanf( "%lld %lld %lld", &n, &k, &last );for( int i = 1, d;i < n;i ++ ) {scanf( "%lld", &d );it[i] = node( i, i - 1, i + 1, d - last );q.push( Node( i, d - last ) );last = d;}it[0].val = it[n].val = 1e15;for( int i = 1;i <= k;i ++ ) {while( vis[q.top().id] ) q.pop(); int val = q.top().val, x = q.top().id;q.pop(), ans += val;vis[it[x].l] = vis[it[x].r] = 1;it[x].val = it[it[x].l].val + it[it[x].r].val - it[x].val;q.push( Node( x, it[x].val ) );Delete( x );}printf( "%lld\n", ans );return 0;
}

[NOI2010] 超级钢琴

source

对于每个iii,将其符合要求的区间扔进队列,确定最大值的位置pospospos

可以使用ststst表预处理最大值位置

然后大根堆,开始选择

一段区间最大值知晓了,次大值一定是在最大值的左边或者右边(刨除最大值位置)

所以直接将区间划成两部分扔进大根堆,要保证区间存在

#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 500005
int n, k, L, R;
int sum[maxn];
int st[maxn][20];void init() {for( int i = 1;i <= n;i ++ ) st[i][0] = i;for( int j = 1;j < 20;j ++ )for( int i = 1;i + ( 1 << j ) - 1 <= n;i ++ )if( sum[st[i + ( 1 << j - 1 )][j - 1]] > sum[st[i][j - 1]] )st[i][j] = st[i + ( 1 << j - 1 )][j - 1];elsest[i][j] = st[i][j - 1];
}int query( int l, int r ) {int i = log2( r - l + 1 );if( sum[st[l][i]] >= sum[st[r - ( 1 << i ) + 1][i]] )return st[l][i];elsereturn st[r - ( 1 << i ) + 1][i];
}struct node {int s, l, r, t;node( int S, int L, int R ) { s = S, l = L, r = R, t = query( l, r ); }bool operator < ( node MS ) const { return sum[t] - sum[s - 1] < sum[MS.t] - sum[MS.s - 1]; }
};
priority_queue < node > q;int main() {scanf( "%d %d %d %d", &n, &k, &L, &R );for( int i = 1;i <= n;i ++ ) {scanf( "%d", &sum[i] );sum[i] += sum[i - 1];}init();for( int i = 1;i <= n - L + 1;i ++ )q.push( node( i, i + L - 1, min( i + R - 1, n ) ) );long long ans = 0;while( k -- ) {node now = q.top(); q.pop();ans += sum[now.t] - sum[now.s - 1];if( now.t != now.l ) q.push( node( now.s, now.l, now.t - 1 ) );if( now.t != now.r ) q.push( node( now.s, now.t + 1, now.r ) );}printf( "%lld\n", ans );return 0;
}

「LibreOJ β Round」ZQC 的手办

source

超级钢琴的父版

操作111直接线段树标记维护

操作222因为保证xxx总和不会很大,那么类似超级钢琴一样将区间切成两部分那种

用线段树查区间最小值以及最小值位置

#include <queue>
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 500005
#define inf 0x7f7f7f7f
#define lson num << 1
#define rson num << 1 | 1
#define Pair pair < int, int >
void read(int &x) {x = 0;char s = getchar();while (s < '0' || s > '9')s = getchar();while ('0' <= s && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48);s = getchar();}
}
struct node {int l, r;Pair ret;node() {}node(int L, int R, Pair p) {l = L, r = R, ret = p;}bool operator < (const node &t) const {return ret.first > t.ret.first;}
};
priority_queue < node > q;
int a[maxn], ans[maxn];
int t[maxn << 2], pos[maxn << 2], tag[maxn << 2];void pushup(int num) {if (t[lson] <= t[rson])t[num] = t[lson], pos[num] = pos[lson];elset[num] = t[rson], pos[num] = pos[rson];
}void build(int num, int l, int r) {if (l == r) {t[num] = a[l];pos[num] = l;return;}int mid = (l + r) >> 1;build(lson, l, mid);build(rson, mid + 1, r);pushup(num);
}void pushdown(int num) {t[lson] = max(t[lson], tag[num]);t[rson] = max(t[rson], tag[num]);tag[lson] = max(tag[lson], tag[num]);tag[rson] = max(tag[rson], tag[num]);tag[num] = 0;
}void modify(int num, int l, int r, int L, int R, int k) {if (t[num] >= k)return;if (R < l || r < L)return;if (L <= l && r <= R) {t[num] = max(t[num], k);tag[num] = max(tag[num], k);return;}pushdown(num);int mid = (l + r) >> 1;modify(lson, l, mid, L, R, k);modify(rson, mid + 1, r, L, R, k);pushup(num);
}Pair query(int num, int l, int r, int L, int R) {if (r < L || R < l)return make_pair(inf, inf);if (L <= l && r <= R)return make_pair(t[num], pos[num]);pushdown(num);int mid = (l + r) >> 1;Pair ans1 = query(lson, l, mid, L, R);Pair ans2 = query(rson, mid + 1, r, L, R);if (ans1.first <= ans2.first)return ans1;elsereturn ans2;
}int main() {int n, m;read(n);for (int i = 1; i <= n; i ++)read(a[i]);build(1, 1, n);read(m);for (int i = 1, opt, a, b, k, x; i <= m; i ++) {read(opt), read(a), read(b), read(k);if (opt & 1)modify(1, 1, n, a, b, k);else {read(x);while (! q.empty())q.pop();int cnt = 0;q.push(node(a, b, query(1, 1, n, a, b)));while (! q.empty() && cnt < x) {node now = q.top();q.pop();int val = now.ret.first, pos = now.ret.second;if (val >= k)break;elseans[++ cnt] = val;if (pos != now.l)q.push(node(now.l, pos - 1, query(1, 1, n, now.l, pos - 1)));if (pos != now.r)q.push(node(pos + 1, now.r, query(1, 1, n, pos + 1, now.r)));}if (cnt < x)printf("-1\n");else {for (int i = 1; i <= x; i ++)printf("%d ", ans[i]);printf("\n");}}}return 0;
}

专题突破二之优先队列、st表——,Running Median,Sequence,Buy Low Sell High,数据备份,超级钢琴,ZQC的手办相关推荐

  1. 51nod 2206 低买高卖codeforces867E Buy Low Sell High 贪心+优先队列

    考虑股票市场,一共有n天. 对于第i天,B君知道股票的价格是每单位a[i]元 在每一天,B君可以选择买入一个单位的股票,卖出一个单位的股票,或者什么都不做. 刚开始B君有无穷多的钱,但是没有任何股票. ...

  2. 【专题】用ST表解决RMQ刷题总结

    [专题]用ST表解决RMQ刷题总结 看了一下上次写博客居然是好久以前的事了(我真是老懒狗了 ) 开门见山,直接放专题链接和代码 kuangbin rmq专题 这个contest里面一共十道题但是实际上 ...

  3. NOIp 数据结构专题总结 (1):STL、堆、并查集、ST表、Hash表

    系列索引: NOIp 数据结构专题总结 (1) NOIp 数据结构专题总结 (2) STL structure std::vector #include <vector> std::vec ...

  4. P2216 [HAOI2007]理想的正方形 ( 二维ST表 )

    题目链接:点击进入 题目 思路 maxx [ i ] [ j ] :左上角坐标 ( i , j ) ,边长为 2 k 2^k 2k 的正方形的最大值 minn [ i ] [ j ] :左上角坐标 ( ...

  5. P2048 [NOI2010] 超级钢琴(ST表 + 优先队列优化)

    P2048 [NOI2010] 超级钢琴 题目 小 Z 是一个小有名气的钢琴家,最近 C 博士送给了小 Z 一架超级钢琴,小 Z 希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出 ...

  6. 【华为机考】专题突破 第一周:单调栈 739 、503 、901、84

    刷题顺序参考于 <2023华为机考刷题指南:八周机考速通车> 前言 单调栈:分为单调递增和单调递减栈.(栈内元素成递增或者递减性): 单调递增栈:从栈底到栈顶数据是从大到小,即 栈内的元素 ...

  7. 倍增算法入门 超详细解答+LCA+RMQ(ST表)+例题剖析

    目录 一.倍增算法 二.倍增算法的应用:求LCA(最近公共祖先)附模板题 三.倍增算法的应用:RMQ 问题(ST表)附模板题 一.倍增算法 要了解倍增之前,强烈建议大家先看一下这位大佬对倍增的解释:[ ...

  8. 「mysql优化专题」你们要的多表查询优化来啦!请查收(4)

    上一篇讲的是单表查询的优化,(本文末有链接).当然,对数据表的多表查询也是必不可少的.本篇内容主要讲解多表联合查询的优化 一.多表查询连接的选择: 相信这内连接,左连接什么的大家都比较熟悉了,当然还有 ...

  9. 牛客练习赛 67——ST表

    A.牛牛爱字符串 注意原字符串有空格,不要用cin #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC o ...

最新文章

  1. c++ STL 常用容器元素类型相关限制 指针 引用
  2. 【新书】用Python3六步掌握机器学习第二版,469页pdf,Mastering Machine Learning
  3. Settings(系统设置app)
  4. github中origin和upstream的区别(转)
  5. .NET轻量级ORM框架Dapper入门精通
  6. 【BZOJ4500】矩阵(差分约束)
  7. 科学家研究:生女有撇步 多钙少碰香蕉
  8. moxy json介绍_使用MOXy 2.5.1快速且有点脏的JSON模式生成
  9. aix查看oracle用户密码,AIX详细查看用户/进程使用内存
  10. python网络爬虫--BeautifulSoup
  11. 【转】Visio(流程图绘制软件)的免费替代品
  12. 教学案例 计算机,计算机教学案例
  13. 利用Matlab进行图像处理
  14. Wireless-AC 8265 CentOS7 无线网卡驱动安装
  15. Excel画的图复制到Word中变形的解决办法
  16. Python实现猜词游戏 Hangman Game(不带提示和带提示版本)
  17. electron的单元测试(基于mocha+chai+karma)
  18. 电动汽车电气及动力系统全解析
  19. pyhton学习之找出单词的个数并进行排序
  20. jquery 设置按钮变成灰色和不可用

热门文章

  1. Java交流|面试最后一问:你有什么问题想问我吗?
  2. vue从url中获取token并加入到 请求头里_BATJ都会用到的接口鉴权cookie、session 和token...
  3. php 命名空间(,PHP命名空间(Namespace)简明教程
  4. linux 虚拟机挂载本地,CentOS 在VMWare中挂载本地yum源
  5. java代码实现链表_java单链表代码实现
  6. linux下找不到libc 库,Linux-覆盖libc open()库函数
  7. 算法题目——爬楼梯(动态规划)
  8. iphone桌面横屏设置在哪里_我和我各司其职的桌面们
  9. 7-6 列出连通集 (25 分)(详解)
  10. html列表变成三个一行,HTML列表仅限第一行缩进