链接:http://codeforces.com/problemset/problem/831/E
思路:看成一个环,每次找到一个上次移除位置的前面一个最小值的位置,计算位置差,已经移除的空位用树状数组维护。
//QAQ
//#pragma comment(linker, "/stack:1024000000,1024000000")
#include <bits/stdc++.h>
/*
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
*/
using namespace std;
#define INF 0x3f3f3f3f
#define MAXM 100005
const double eps = 1e-8;
const double PI = acos(-1.0);
const long long mod=1e9+7;
const int MAXN = 1e6+7;
int a[MAXN];
long long b[MAXN];
vector<int> v[MAXN];
int lowbit(int x)
{
return x&-x;
}
long long sum(int x)
{
long long ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
void add_(int x, long long num)
{
while(x<=MAXN)
{
b[x]+=num;
x+=lowbit(x);
}
}
int main()
{
int n;
long long ans=0;
scanf("%d",&n);
for(int i=0; i<n; ++i)
{
scanf("%d",&a[i]);
v[ a[i] ].push_back(i+1);
}
sort(a,a+n);
int m=unique(a,a+n)-a;
int pre=0;
for(int i=0; i<m; ++i)
{
int poi=lower_bound(v[ a[i] ].begin(), v[ a[i] ].end(), pre)-v[ a[i] ].begin();
if(!poi)
{
poi=v[ a[i] ][ v[a[i]].size()-1 ];
ans+=poi-pre-sum(poi)+sum(pre);
}
else
{
poi=v[a[i]][poi-1];
ans+=n-pre+poi-sum(n)+sum(pre)-sum(poi);
}
pre=poi;
int k=v[a[i]].size();
for(int j=0; j<k; ++j)
add_(v[a[i]][j],1);
}
cout<<ans<<endl;
return 0;
}
/*
4
6 3 1 2
*/