思路:
就是 你好像就是要维护一下,你pop的当前值与之前的pop值的位置之间有多少个要移一移,然后算一下,然后就变成了模拟。。
线段树维护 值 和 位置,树状数组维护已经取了没有。
7
6 3 1 5 4 4 3
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int val[N], n;
struct Seg{
int id;
int w;
int Left, Right;
}node[N<<2];
void Build(int num, int Left, int Right){
node[num].Left = Left;
node[num].Right = Right;
if(Left == Right){
node[num].id = Left;
node[num].w = val[Left];
return;
}
int Mid = (Left + Right) >> 1;
Build(num<<1, Left, Mid);
Build(num<<1|1, Mid + 1, Right);
node[num].w = node[num<<1].w < node[num<<1|1].w?node[num<<1].w:node[num<<1|1].w;
node[num].id = node[num<<1].w < node[num<<1|1].w?node[num<<1].id:node[num<<1|1].id;
if(node[num<<1].w == node[num<<1|1].w)
node[num].id = node[num<<1].id < node[num<<1|1].id?node[num<<1].id:node[num<<1|1].id;
}
void Update(int num, int v){
if(node[num].Left == node[num].Right){
if(node[num].Left == v){
node[num].w = INF;
}
return;
}
int Mid = (node[num].Left + node[num].Right) >> 1;
if(Mid >= v) Update(num<<1, v);
else Update(num<<1|1, v);
node[num].w = node[num<<1].w < node[num<<1|1].w?node[num<<1].w:node[num<<1|1].w;
node[num].id = node[num<<1].w < node[num<<1|1].w?node[num<<1].id:node[num<<1|1].id;
if(node[num<<1].w == node[num<<1|1].w)
node[num].id = node[num<<1].id < node[num<<1|1].id?node[num<<1].id:node[num<<1|1].id;
}
Seg Query(int num, int s, int t){
if(node[num].Left >= s && node[num].Right <= t)
return node[num];
int Mid = (node[num].Left + node[num].Right) >> 1;
if(Mid >= t) return Query(num<<1, s, t);
else if(Mid < s) return Query(num<<1|1, s, t);
else{
Seg temp1,temp2;
temp1 = Query(num<<1, s, Mid);
temp2 = Query(num<<1|1, Mid+1, t);
if(temp1.w < temp2.w) return temp1;
if(temp1.w == temp2.w){
if(temp1.id < temp2.id) return temp1;
return temp2;
}
return temp2;
}
}
LL c[N];
int lowbit(int v){
return v&(-v);
}
LL Sum(int v){
LL res = 0;
while(v>0){
res += c[v];
v-=lowbit(v);
}
return res;
}
void add(int v,LL x){
while(v<=n){
c[v] += x;
v += lowbit(v);
}
}
LL kk(int pre, int now){
if(pre == now) return 1LL;
LL res = 0;
if(now > pre)
return Sum(now) - Sum(pre);
else
return Sum(n) - Sum(pre) + Sum(now);
}
void solve(){
LL res = 0;
Seg temp;
int sum = 1;
int Mimi, pos;
int Last = 1;
while(sum <= n){
Mimi = val[sum];
temp = Query(1,Last, n);
if(temp.w == val[sum]){
res = res + kk(Last-1, temp.id);
add(temp.id, -1);
Update(1, temp.id);
Last = temp.id;
}
else{
temp = Query(1,1, Last-1);
res = res + kk(Last, temp.id);
add(temp.id, -1);
Update(1,temp.id);
Last = temp.id;
}
sum++;
}
printf("%lld\n",res);
}
int main(){
scanf("%d", &n);
for(int i=1;i<=n;i++){
add(i,1LL);
scanf("%d",&val[i]);
}
Build(1,1,n);
sort(val+1, val+n+1);
solve();
return 0;
}