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.

Input

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.

Output

Print the total number of times Vasily takes the top card from the deck.

Examples
input
4
6 3 1 2
output
7
input
1
1000
output
1
input
7
3 3 3 3 3 3 3
output
7
Note

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.

题意:

n个数,

1、可以将数整体向左移,

2、如果最左边的数在剩余的数中最小,可以删去最左边的数

两个操作的花费都是1,问将所有的数删去所需要的代价

线段树

记录当前序列的最右端R在哪儿

R左边的数表示实际移到了后面,R右边的数实际在前面

移动带来的线段树中节点大小的改变,通过记录节点大小解决

每次查询在R前面查一次,在R后面查一次

注意如果前面后面的值相等,选R后面的

#include<cstdio>
#include<algorithm>
#define N 100001 #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif using namespace std;
int n,R,tmp1,tmp2,opl,opr;
long long ans;
int sum[N<<],minn[N<<],pos[N<<],mid[N<<],a[N];
void up(int k)
{
sum[k]=sum[k<<]+sum[k<<|];
minn[k]=min(minn[k<<],minn[k<<|]);
if(minn[k]==minn[k<<]) pos[k]=pos[k<<];
else pos[k]=pos[k<<|];
}
void build(int k,int l,int r)
{
if(l==r)
{
scanf("%d",&a[l]);
minn[k]=a[l]; sum[k]=; pos[k]=l;
return;
}
mid[k]=l+r>>;
build(k<<,l,mid[k]);
build(k<<|,mid[k]+,r);
up(k);
}
int find_minn(int k,int l,int r)
{
if(l>=opl && r<=opr) return pos[k];
if(opr<=mid[k]) return find_minn(k<<,l,mid[k]);
else if(opl>mid[k]) return find_minn(k<<|,mid[k]+,r);
{
int t1=find_minn(k<<,l,mid[k]);
int t2=find_minn(k<<|,mid[k]+,r);
if(a[t1]<=a[t2]) return t1;
return t2;
}
}
int query(int k,int l,int r)
{
if(l>=opl && r<=opr) return sum[k];
if(opr<=mid[k]) return query(k<<,l,mid[k]);
else if(opl>mid[k]) return query(k<<|,mid[k]+,r);
return query(k<<,l,mid[k])+query(k<<|,mid[k]+,r);
}
void delet(int k,int l,int r)
{
if(l==r)
{
sum[k]=; pos[k]=l;
minn[k]=a[l]=N+;
return;
}
if(opl<=mid[k]) delet(k<<,l,mid[k]);
else delet(k<<|,mid[k]+,r);
up(k);
}
int main()
{
scanf("%d",&n);
build(,,n);
R=n+;
for(int i=;i<=n;i++)
{
tmp1=tmp2=;
if(R)
{
opl=; opr=R-;
tmp1=find_minn(,,n);
}
if(R<n)
{
opl=R+; opr=n;
tmp2=find_minn(,,n);
}
if( (tmp1 && tmp2 && a[tmp2]<a[tmp1]) || (tmp2 && !tmp1) )
{
if(tmp2>R) opl=R+,opr=tmp2,ans+=query(,,n);
else
{
if(R<n) opl=R+,opr=n,ans+=query(,,n);
opl=,opr=tmp2,ans+=query(,,n);
}
opl=tmp2; delet(,,n); R=tmp2;
}
else if(tmp1 && tmp2 && a[tmp1]==a[tmp2])
{
opl=R+,opr=tmp2,ans+=query(,,n);
opl=tmp2;delet(,,n); R=tmp2;
}
else
{
if(tmp1>R) opl=R+,opr=tmp1,ans+=query(,,n);
else
{
if(R<n) opl=R+,opr=n,ans+=query(,,n);
opl=,opr=tmp1,ans+=query(,,n);
}
opl=tmp1; delet(,,n); R=tmp1;
}
}
printf(LL,ans);
}

codeforces 830 B Cards Sorting的更多相关文章

  1. codeforces 830 B. Cards Sorting(线段树)

    题目链接:http://codeforces.com/contest/830/problem/B 题解:其实这题就是求当前大小的数到下一个大小的数直接有多少个数,这时候可以利用数据结构来查询它们之间有 ...

  2. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) E. Cards Sorting 树状数组

    E. Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  3. Codeforces 830B - Cards Sorting 树状数组

    B. Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  4. AC日记——Cards Sorting codeforces 830B

    Cards Sorting 思路: 线段树: 代码: #include <cstdio> #include <cstring> #include <iostream> ...

  5. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Cards Sorting(树状数组)

    Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  6. Codeforces Round #424 Div2 E. Cards Sorting

    我只能说真的看不懂题解的做法 我的做法就是线段树维护,毕竟每个数的顺序不变嘛 那么单点维护 区间剩余卡片和最小值 每次知道最小值之后,怎么知道需要修改的位置呢 直接从每种数维护的set找到现在需要修改 ...

  7. Codeforces Round #424 E. Cards Sorting

    题目大意:给你一堆n张牌(数字可以相同),你只能从上面取牌,如果是当前牌堆里面最小的值则拿走, 否则放到底部,问你一共要操作多少次. 思路:讲不清楚,具体看代码.. #include<bits/ ...

  8. 【Splay】Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) B. Cards Sorting

    Splay要支持找最左侧的最小值所在的位置.类似线段树一样处理一下,如果左子树最小值等于全局最小值,就查左子树:否则如果当前节点等于全局最小值,就查当前节点:否则查右子树. 为了统计答案,当然还得维护 ...

  9. CodeForces 830B - Cards Sorting

    将每个数字的位置存进该数字的vector中 原数组排个序从小到大处理,每次在vector里二分找到距离当前位置“最远”的位置(相差最大),更新答案 树状数组维护每个数字现在的位置和原位置之差 #inc ...

随机推荐

  1. 【BZOJ2959】长跑(Link-Cut Tree,并查集)

    [BZOJ2959]长跑(Link-Cut Tree,并查集) 题面 BZOJ 题解 如果保证不出现环的话 妥妥的\(LCT\)傻逼题 现在可能会出现环 环有什么影响? 那就可以沿着环把所有点全部走一 ...

  2. 2014NOIP普及组 子矩阵

    觉得题目水的离开 觉得普及组垃圾的请离开 不知道 DFS 和 DP 的请离开 不屑的大佬请离开 ……. 感谢您贡献的访问量 ————————————————华丽的分割线 ——————————————— ...

  3. Graham凸包算法简介

    凸包真是一个神奇的算法.. 概念 凸包,我理解为凸多边形 叉积 对于向量AB和向量BC,记向量AB*向量BC = AB * BC * sin ∠ABC,而叉积的绝对值其实就是S△ABC/2 对于平面上 ...

  4. Y2 MyBatis(二)

    春节后的第一次课 1.整合日志(log4j和logback) (1)log4j和logback都是一个日志记录框架 (2)appender记住两个 stdout控制台显示日志,file记录文件中 (3 ...

  5. python—day02

    python的版本与基本类型... 第一: 讲了计算机的基础的补充,讲解了什么是操作系统,计算机硬件,应用程序之间的关系: 操作系统是一个能协调管理计算机软件与硬件的软件程序: 能帮我们发送指令集到C ...

  6. RedissonLock分布式锁源码分析

    最近碰到的一个问题,Java代码中写了一个定时器,分布式部署的时候,多台同时执行的话就会出现重复的数据,为了避免这种情况,之前是通过在配置文件里写上可以执行这段代码的IP,代码中判断如果跟这个IP相等 ...

  7. 学习python之路_入门篇A

    偶尔经同事的介绍进入了金角大王的博客里,看到大王编写的文章都是关于python编程的,由于自己一直也是做软件测试方面的工作,也一直想往自动化测试方面发展,了解到利用python可以进行自动化测试操作, ...

  8. Unity3D项目程序加密-VirboxProtector加壳工具

    各位Unity3D的开发者,你还为你的代码被反编译而头疼, 混淆和加密已经失效,为内存dump代码而烦恼?是否辛苦制作的游戏被盗版被抄袭而烦恼? 是否害怕算法被别人参考要把算法写成C++而费劲周折? ...

  9. Linux远程连接工具

    Linux远程连接可以使用SecureCRT工具完成 SecureCRT下载地址 修改虚拟机中的网络适配器---改为桥接模式 一,配置:在Linux终端上获取IP地址----ifconfig 二,同时 ...

  10. 设计模式 --> (14)中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互.中介者模式的例子很多,大到联合国安理会,小到房屋中介,都扮演了 ...