#424 Div2 E

题意

给出一个 n 个数的数列,从前往后取数,如果第一个数是当前数列的最小值,则取出,否则将它放到数列尾端,问使数列为空需要多少步操作。

分析

用数据结构去模拟。

线段树维护区间最小值及取得最小值的位置。树状数组维护仍存在的数的个数( 1 表示未取,0 表示已取)。

首先寻找全局最小值,那么答案加上它前面的存在的数的个数,然后删掉这个值,(在线段树中将这个值置为无穷大等价于删除掉它)。

设这个前面删掉的最小值位置为 idx,那么再从 idx+1 往后找,是否存在全局最小值。

如果存在下标为 pos ,那么答案加上区间 (idx, pos] 仍然存在的数的个数(使用树状数组计算),再把 idx 置为 pos。

如果不存在,答案加上 (idx, n] 仍然存在的数的个数,退出当前循环,从头开始找(即把 idx 置为 0)。

code

#include<bits/stdc++.h>
#define lson l, m, rt * 2
#define rson m + 1, r, rt * 2 + 1
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5;
const int INF = 2e9 + 1;
int a[MAXN];
struct BIT {
int f[MAXN];
void add(int p, int c) {
while(p <= MAXN) {
f[p] += c;
p += (p & -p);
}
}
int query(int p) {
int s = 0;
while(p) {
s += f[p];
p -= (p & -p);
}
return s;
}
} bit;
struct ST {
struct node {
int id, val;
node() {}
node(int id_, int val_):id(id_), val(val_) {}
} ary[MAXN << 2];
node pushUp(node& nd, int rt) {
if(ary[2 * rt].val <= ary[2 * rt + 1].val) {
nd.id = ary[2 * rt].id;
nd.val = ary[2 * rt].val;
} else {
nd.id = ary[2 * rt + 1].id;
nd.val = ary[2 * rt + 1].val;
}
}
void build(int l, int r, int rt) {
if(l == r) {
ary[rt].id = l;
ary[rt].val = a[l];
return;
}
int m = (l + r) / 2;
build(lson);
build(rson);
pushUp(ary[rt], rt);
}
void query(int L, int R, int& pos, int& res, int l, int r, int rt) {
if(L <= l && R >= r) {
if(ary[rt].val < res) {
res = ary[rt].val;
pos = ary[rt].id;
}
return;
}
int m = (l + r) / 2;
if(L <= m) query(L, R, pos, res, lson);
if(R > m) query(L, R, pos, res, rson);
}
void update(int p, int val, int l, int r, int rt) {
if(l == r) {
ary[rt].val = val;
return;
}
int m = (l + r) / 2;
if(m < p) update(p, val, rson);
else update(p, val, lson);
pushUp(ary[rt], rt);
}
} st;
int main() {
int n;
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
bit.add(i, 1);
}
st.build(1, n, 1);
ll ans = 0;
for(int T = 0; T < n;) {
for(int idx = 0; idx < n && T < n;) {
int minV = INF, minv = INF, posV, posv;
st.query(1, n, posV, minV, 1, n, 1);
st.query(idx + 1, n, posv, minv, 1, n, 1);
if(minv != minV) {
ans += bit.query(n) - bit.query(idx);
break;
}
ans += bit.query(posv) - bit.query(idx);
st.update(posv, INF, 1, n, 1);
bit.add(posv, -1);
T++;
idx = posv;
}
}
cout << ans << endl;
return 0;
}

最新文章

  1. java 消息机制 ActiveMQ入门实例
  2. jquery插件:仿百度首页可展开收起的消息提示控件
  3. NHibernate系列文章十一:NHibernate并发控制
  4. hiho(1081),SPFA最短路,(非主流写法)
  5. 40免费的 jQuery &amp; CSS3 图片热点特效
  6. poj - 3268 Silver Cow Party (求给定两点之间的最短路)
  7. MVC 点击下载文档
  8. C语言实现两栈空间共享
  9. Tree( 树) 组件[1]
  10. QTableWidget查找指定项(由github处学习到)
  11. java基础之 第一步 :jdk安装配置
  12. JavaScript Date对象更进一步
  13. 隐马尔可夫模型(HMM)
  14. RMQ算法
  15. [C#] C# 与 Nessus 交互,动态构建扫描任务计划
  16. Linux nohup用法
  17. PostgreSQL 自动输入密码(转)
  18. Hadoop第一阶段总结
  19. Vsftp的PASV mode(被动模式传送)和Port模式及 Linux下VsFTP配置全方案
  20. SnowNLP:•中文分词•词性标准•提取文本摘要,•提取文本关键词,•转换成拼音•繁体转简体的 处理中文文本的Python3 类库

热门文章

  1. 《Cracking the Coding Interview》——第7章:数学和概率论——题目2
  2. Spring+SpringMVC+MyBatis+Redis框架学习笔记
  3. 恢复误删除表黑科技之relay log大法(续)
  4. java开发环境的安装
  5. 孤荷凌寒自学python第十五天python循环控制语句
  6. HA集群基本概念详解
  7. 线段树 (区间更新,区间查询) poj http://poj.org/problem?id=3468
  8. 什么是EM算法?
  9. SQL 基础笔记(二):进阶查询
  10. 存储 磁盘大于2TB 大数据存储一个盘 解决方法