Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组
Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this integer is between 1 and 100 000, inclusive. It is possible that some cards have the same integers on them.
Vasily decided to sort the cards. To do this, he repeatedly takes the top card from the deck, and if the number on it equals the minimum number written on the cards in the deck, then he places the card away. Otherwise, he puts it under the deck and takes the next card from the top, and so on. The process ends as soon as there are no cards in the deck. You can assume that Vasily always knows the minimum number written on some card in the remaining deck, but doesn't know where this card (or these cards) is.
You are to determine the total number of times Vasily takes the top card from the deck.
The first line contains single integer n (1 ≤ n ≤ 100 000) — the number of cards in the deck.
The second line contains a sequence of n integers a1, a2, ..., an (1 ≤ ai ≤ 100 000), where ai is the number written on the i-th from top card in the deck.
Print the total number of times Vasily takes the top card from the deck.
- 4
6 3 1 2
- 7
- 1
1000
- 1
- 7
3 3 3 3 3 3 3
- 7
In the first example Vasily at first looks at the card with number 6 on it, puts it under the deck, then on the card with number 3, puts it under the deck, and then on the card with number 1. He places away the card with 1, because the number written on it is the minimum among the remaining cards. After that the cards from top to bottom are [2, 6, 3]. Then Vasily looks at the top card with number 2 and puts it away. After that the cards from top to bottom are [6, 3]. Then Vasily looks at card 6, puts it under the deck, then at card 3 and puts it away. Then there is only one card with number 6 on it, and Vasily looks at it and puts it away. Thus, in total Vasily looks at 7 cards.
题目大意 桌面上有一叠卡牌,每张卡牌上有些数。当拿起一张卡牌时,如果它上面的数是当前剩下的牌中的数(包括拿起的这一张)的最小值(假定这个人知道),就把它"扔掉",否则把它塞进这叠卡牌的最下面。问把所有卡牌都拿走花了多少次。
然后不说多的废话了。树状数组维护卡牌是否被拿走(拿走为0,未拿走为1),线段树维护区间最小值。
因为移动的话很麻烦,但是一轮后顺序又正常了,所以可以一轮一轮地计算。记录fin(已经拿走的牌的数量)和last(上个拿走的卡牌的下标)。
->当fin等于n时停止
->将last设为1
->找到last右侧的最小值和整叠卡牌的最小值,判断他们是否相等。
*如果相等
->返回最小的最小值下标pos,然后树状数组统计last + 1到pos的和(这中间还有多少没拿走),更新答案。
->将树状数组这一位置为0,线段树中这一位改为inf(不方便delete,就这么干),fin 加 1,将last设为pos。
*如果不相等
->统计last + 1到n的和(把这一轮中剩下的牌都拿完)
->break
Code
- /**
- * Codeforces
- * Problem#831E
- * Accepted
- * Time:109ms
- * Memory:7584k
- */
- #include <iostream>
- #include <cstdio>
- #include <ctime>
- #include <cmath>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- #include <fstream>
- #include <sstream>
- #include <algorithm>
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <vector>
- #include <stack>
- #include <cassert>
- #ifndef WIN32
- #define Auto "%lld"
- #else
- #define Auto "%I64d"
- #endif
- using namespace std;
- typedef bool boolean;
- const signed int inf = (signed)((1u << ) - );
- const signed long long llf = (signed long long)((1ull << ) - );
- const double eps = 1e-;
- const int binary_limit = ;
- #define smin(a, b) a = min(a, b)
- #define smax(a, b) a = max(a, b)
- #define max3(a, b, c) max(a, max(b, c))
- #define min3(a, b, c) min(a, min(b, c))
- template<typename T>
- inline boolean readInteger(T& u){
- char x;
- int aFlag = ;
- while(!isdigit((x = getchar())) && x != '-' && x != -);
- if(x == -) {
- ungetc(x, stdin);
- return false;
- }
- if(x == '-'){
- x = getchar();
- aFlag = -;
- }
- for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
- ungetc(x, stdin);
- u *= aFlag;
- return true;
- }
- #define lowbit(x) (x & (-x))
- typedef class IndexedTree {
- public:
- int *l;
- int size;
- IndexedTree() { }
- IndexedTree(int size):size(size) {
- l = new int[(size + )];
- memset(l, , sizeof(int) * (size + ));
- }
- inline void add(int idx, int val) {
- for(; idx <= size; idx += lowbit(idx)) {
- l[idx] += val;
- }
- }
- inline int getSum(int idx) {
- int ret = ;
- for(; idx; idx -= lowbit(idx))
- ret += l[idx];
- return ret;
- }
- }IndexedTree;
- typedef class SegTreeNode {
- public:
- int minid;
- int val;
- SegTreeNode *l, *r;
- SegTreeNode() { }
- inline void pushUp() {
- if(l->val <= r->val)
- minid = l->minid, val = l->val;
- else
- minid = r->minid, val = r->val;
- }
- }SegTreeNode;
- typedef class SegTree {
- public:
- SegTreeNode* root;
- SegTree() { }
- SegTree(int n, int* lis) {
- build(root, , n, lis);
- }
- void build(SegTreeNode* &node, int l, int r, int *lis) {
- node = new SegTreeNode();
- if(l == r) {
- node->minid = l, node->val = lis[l];
- return;
- }
- int mid = (l + r) >> ;
- build(node->l, l, mid, lis);
- build(node->r, mid + , r, lis);
- node->pushUp();
- }
- void update(SegTreeNode* &node, int l, int r, int idx, int val) {
- if(l == idx && r == idx) {
- node->val = val;
- return;
- }
- int mid = (l + r) >> ;
- if(idx <= mid) update(node->l, l, mid, idx, val);
- else update(node->r, mid + , r, idx, val);
- node->pushUp();
- }
- void query(SegTreeNode*& node, int l, int r, int ql, int qr, int& idx, int& minv) {
- if(l == ql && r == qr) {
- if(node->val < minv)
- idx = node->minid, minv = node->val;
- return;
- }
- int mid = (l + r) >> ;
- if(qr <= mid) query(node->l, l, mid, ql, qr, idx, minv);
- else if(ql > mid) query(node->r, mid + , r, ql, qr, idx, minv);
- else {
- int a = -, b = inf;
- query(node->l, l, mid, ql, mid, a, b);
- query(node->r, mid + , r, mid + , qr, idx, minv);
- if(b <= minv) {
- minv = b, idx = a;
- }
- }
- }
- }SegTree;
- int n;
- int *a;
- IndexedTree st;
- SegTree st1;
- inline void init() {
- readInteger(n);
- a = new int[n + ];
- for(int i = ; i <= n; i++) {
- readInteger(a[i]);
- }
- }
- long long res = ;
- inline void solve() {
- st = IndexedTree(n);
- st1 = SegTree(n, a);
- for(int i = ; i <= n; i++) st.add(i, );
- for(int fin = ; fin < n; ) {
- for(int last = ; fin < n && last < n; ) {
- int stand, idx, minv1 = inf, minv2 = inf;
- st1.query(st1.root, , n, , n, stand, minv1);
- st1.query(st1.root, , n, last + , n, idx, minv2);
- if(minv1 != minv2) {
- res += st.getSum(n) - st.getSum(last);
- break;
- }
- res += st.getSum(idx) - st.getSum(last);
- st.add(idx, -);
- st1.update(st1.root, , n, idx, inf);
- fin++;
- last = idx;
- }
- }
- printf(Auto, res);
- }
- int main() {
- init();
- solve();
- return ;
- }
Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组的更多相关文章
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 831C) - 暴力 - 二分法
Polycarp watched TV-show where k jury members one by one rated a participant by adding him a certain ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem F (Codeforces 831F) - 数论 - 暴力
题目传送门 传送门I 传送门II 传送门III 题目大意 求一个满足$d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil - \sum ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划
There are n people and k keys on a straight line. Every person wants to get to the office which is l ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块
Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem A - B
Array of integers is unimodal, if: it is strictly increasing in the beginning; after that it is cons ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心
Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集
Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) A 水 B stl C stl D 暴力 E 树状数组
A. Unimodal Array time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)
http://codeforces.com/contest/831 A. Unimodal Array time limit per test 1 second memory limit per te ...
随机推荐
- cocos2d JS 艺术字特殊符号的显示
this.setSocreAtion(score, this.tfMoneyList[index],mun); //传入分数与对象,调用下面的函数 setSocreAtion : function ( ...
- 自定django登录跳转限制
django自定义一个登录跳转限制: 解释: 不登录不让跳转到其它页面. 原理: 做一个装饰器,在访问路由时,先进行判断,登录session是否存在,如果存在则跳转,不存在则返回到登录页面.或者你可以 ...
- vue中使用base64和md5
1.在项目根目录下安装 cnpm install --save js-base64 cnpm install --save js-md5 2.在项目文件中引入 import md5 from 'js- ...
- C++实现 safaBase64编码跟nonSafeBase64编码的转换
默认Base64编码的字符串,用于网络传输是不安全的,因为Base64编码使用的标准字典含有“+”,“/”. 规则如下: //nonSafeBase64 到 safeBase64'+' ------ ...
- MySQL.Linux.安装
Linux 7.x.安装 MySQL 环境: linux是安装在虚拟机中的,宿主机是:win10系统.安装MySQL的时候,首先需要网络是通的(宿主机和虚拟机之间通信).相关配置,参见:虚拟机和宿主机 ...
- es6Math对象新增的方法
Math.trunc() Math.trunc方法用于去除一个数的小数部分,返回整数部分. 对于没有部署这个方法的环境,可以用下面的代码模拟. Math.trunc = Math.trunc || f ...
- C# 基于Aspose.Cells的数据导出到Excel
using Aspose.Cells; void WriteToExcel(string filePath, List<object[]> datas, string sheetName ...
- python遍历某一位置所有文件夹中的文件
通过多次遍历达到找出所有文件的目的 import os rootdir=["d:/77"] c=[] for i in rootdir: for parent,dirnames,f ...
- 08 集合[11,22,33,44,55,66,77,88,99],将所有<66的值保存至字典的第一个key中,将所有>=66的值保存至字典的第二个key中。即:{'k1':<66的所有值,'k2':>=66的所有值}
li = [11,22,33,44,55,66,77,88,99]dict = {'k1':[],'k2':[]}for i in li: if i < 66: dict[& ...
- hdu3037 lucas
题意 : 给了n课不同的树,要求将 0,1,2,3,4,5,...m个松果,分别放在n棵树上的方案数有多少, 我们这样考虑, 如果将m个相同的松果 放入n棵树中 , 转化一下,我们让每个点至少放1个 ...