CF1227D Optimal Subsequences
思路:
首先对于单个查询(k, p)来说,答案一定是a数组中的前k大数。如果第k大的数字有多个怎么办?取索引最小的若干个。所以我们只需对a数组按照值降序,索引升序排序即可。
多个查询怎么办?离线处理。依然是对数组a按照上面的方法排序,然后对所有的查询按照k升序排序,分别离线计算。具体做法是,按顺序扫描a,用一个集合动态维护前k大的数,当发现某个查询正好询问前k大时,即时处理即可。
那么如何从一个集合中快速找到第k大数?c++标准库中原始的set是不行的,可以用1. 二分+树状数组(或线段树)2. __gnu_pbds https://www.geeksforgeeks.org/ordered-set-gnu-c-pbds/
实现1(二分+树状数组,n * log(n) * log(n)):
#include <bits/stdc++.h> using namespace std;
const int MAXN = ;
typedef pair<int, int> pii; int a[MAXN + ], bit[MAXN + ]; int lowbit(int x) { return x & -x; } void add(int i, int x)
{
while (i <= MAXN) { bit[i] += x; i += lowbit(i); }
} int sum(int i)
{
int ans = ;
while (i) { ans += bit[i]; i -= lowbit(i); }
return ans;
} bool cmp(pii& a, pii& b)
{
if (a.first != b.first) return a.first > b.first;
return a.second < b.second;
} void work(pii& q, map<pii, int>& mp)
{
int k = q.first, p = q.second;
int l = , r = MAXN, res = -;
while (l <= r)
{
int m = l + r >> ;
if (sum(m) < p) l = m + ;
else { res = m; r = m - ; }
}
assert(res != -);
mp[q] = res;
} int main()
{
ios::sync_with_stdio(false);
int n, m;
while (cin >> n)
{
memset(bit, , sizeof bit);
vector<int> a(n);
for (int i = ; i < n; i++) cin >> a[i];
vector<pii> b(n);
for (int i = ; i < n; i++) { b[i].first = a[i]; b[i].second = i + ; }
sort(b.begin(), b.end(), cmp);
cin >> m;
vector<pii> q(m);
for (int i = ; i < m; i++) cin >> q[i].first >> q[i].second;
vector<pii> sorted_q(q.begin(), q.end());
sort(sorted_q.begin(), sorted_q.end());
map<pii, int> res;
int cur = ;
for (int i = ; i < n; i++)
{
add(b[i].second, );
while (cur < m && i + == sorted_q[cur].first)
{
work(sorted_q[cur], res);
cur++;
}
}
for (auto it: q)
{
int id = res[it];
cout << a[id - ] << endl;
}
}
return ;
}
实现2(__gnu_pbds,n * log(n)):
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> using namespace std;
using namespace __gnu_pbds; typedef pair<int, int> pii;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; bool cmp(pii& a, pii& b)
{
if (a.first != b.first) return a.first > b.first;
return a.second < b.second;
} int main()
{
ios::sync_with_stdio(false);
int n, m;
while (cin >> n)
{
vector<int> a(n);
for (int i = ; i < n; i++) cin >> a[i];
vector<pii> b(n);
for (int i = ; i < n; i++) { b[i].first = a[i]; b[i].second = i + ; }
sort(b.begin(), b.end(), cmp);
cin >> m;
vector<pii> q(m);
for (int i = ; i < m; i++) cin >> q[i].first >> q[i].second;
vector<pii> sorted_q(q.begin(), q.end());
sort(sorted_q.begin(), sorted_q.end());
map<pii, int> res;
int cur = ;
ordered_set st;
for (int i = ; i < n; i++)
{
st.insert(b[i].second);
while (cur < m && i + == sorted_q[cur].first)
{
res[sorted_q[cur]] = *st.find_by_order(sorted_q[cur].second - );
cur++;
}
}
for (auto it: q)
{
cout << a[res[it] - ] << endl;
}
}
}
CF1227D Optimal Subsequences的更多相关文章
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2. Optimal Subsequences (Hard Version) 数据结构 贪心
D2. Optimal Subsequences (Hard Version) This is the harder version of the problem. In this version, ...
- CF-Technocup3 D Optimal Subsequences
D Optimal Subsequences http://codeforces.com/contest/1227/problem/D2 显然,每次求的k一定是这个序列从大到小排序后前k大的元素. 考 ...
- Codeforces 1262D Optimal Subsequences(BIT+二分)
首先比较容易想到肯定是前k大的元素,那么我们可以先对其进行sort,如果数值一样返回下标小的(见题意),接下里处理的时候我们发现需要将一个元素下标插入到有序序列并且需要访问第几个元素是什么,那么我们可 ...
- Optimal Subsequences(主席树)
题意: 给定一个序列,长度为n(<=2e5),有m(<=2e5)个询问,每个询问包含k和pos,要从原序列中选出一个长度为k的子序列,要求是这个序列的和是所有长度为k的序列中最大的,且是字 ...
- D2. Optimal Subsequences (Hard Version) 主席树
题目链接:https://codeforces.com/contest/1262/problem/D2 将数组按大到小排序(相同大小的按下标由小到大排序),依次将排序后的每个数在原数组中的位置放入主席 ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) - D2. Optimal Subsequences (Hard Version)(主席树)
题意:一共有$n$个数,$m$次询问,每次询问包括$k.pos$两个数,需要你从这$n$个数里面找出$k$个数,使得他们的总和最大,如果有多种情况,找出序号字典序最小的一组,然后输出这个序列中第$po ...
- codeforces 1262D Optimal Subsequences 主席树询问第k小
题意 给定长度为\(n\)的序列\(a\),以及m个询问\(<k,pos>\),每次询问满足下列条件的子序列中第\(pos\)位的值为多少. 子序列长度为\(k\) 序列和是所有长度为\( ...
- Codeforces Round #602 Div2 D1. Optimal Subsequences (Easy Version)
题意:给你一个数组a,询问m次,每次返回长度为k的和最大的子序列(要求字典序最小)的pos位置上的数字. 题解:和最大的子序列很简单,排个序就行,但是题目要求字典序最小,那我们在刚开始的时候先记录每个 ...
- 笔记 - 数据结构 - 区间第k大
Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2 - Optimal Subsequence ...
随机推荐
- 1-STM32+W5500+GPRS物联网开发基础篇-工控板简介
最近这些日子都在忙活STM+W5500+GPRS的板子,所以前面的那块板子的教程耽搁了些时间. 这次的板子和上一版相比更贴近了使用,是因为有朋友督促我要做一块直接可以在工厂使用的板子,所以设计了这一块 ...
- 2017.10.6 国庆清北 D6T3 字符串
题目描述 如果把一个字符串从头到尾翻转后和原字符串相等,我们称之为回文串,比如“aabaa”.“())(”.“2017102”. 如果一个字符串存在两个出现过的字母出现的次数相等,我们称之为好 的字符 ...
- 生成ROM时修改参数
在Xilinx ISE中生成ROM后,如果修改参数,可能会出现错误: “The Memory Initialization vector can contain between 1 to Write” ...
- beego 前后端分离登录验证
conf>app.conf 文件添加一下参数 copyrequestbody=true sessionon =true routers>router.go 文件添加初始化路由 func i ...
- 使用docker安装wazuh
使用docker安装wazuh centos下安装wazuh 官方文档: https://documentation.wazuh.com/3.9/installation-guide/installi ...
- 用avalon框架怎么做轮播图?
avalon这个框架其实特别的小众,做个轮播图呢?在github上的例子只有一个,而且功能特别的少,有的引入的插件与avalon里面的指令又不兼容,所以找了一个owl-carousel,目前实现了移动 ...
- CFD计算过程发散诸多原因分析【转载】
转载自: http://blog.sina.com.cn/s/blog_5fdfa7e601010rkx.html 今天探讨引起CFD计算过程中发散的一些原因.cfd计算是将描述物理问题的偏微分方程转 ...
- 初识kubernetes
Kubernetes最初源于谷歌内部的Borg,提供了面向应用的容器集群部署和管理系统.Kubernetes 的目标旨在消除编排物理/虚拟计算,网络和存储基础设施的负担,并使应用程序运营商和开发人员完 ...
- centos6安装vim插件youcompleteme问题及解决
首先clone vim8代码库 git clone https://github.com/vim/vim.git 然后编译 注意下自己的python2.7config在哪儿 ./configure - ...
- python gdal ogr osgeo