Codeforces-831E Cards Sorting(树状数组)

来源:互联网 发布:剑灵24人本优化不卡 编辑:程序博客网 时间:2024/06/06 15:42

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

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
46 3 1 2
output
7
input
11000
output
1
input
73 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 7cards.


题意:n个牌,牌上有数,每次从牌顶抽取一张牌,如果这张牌是当前的最小值那么就把它扔掉,不然放到牌堆底,问需要多少次操作把牌扔光。

题解:树状数组
树状数组中记录位置i是否有牌,1为有牌,0位没有牌
首先将数字排序,把数字在原数组中的位置存入vector中,v[i][j]表示第i大的数中第j小的位置(因为有的数会重复出现)

不妨假设有sz个不同的数,从最小的数开始模拟
假如当前是数字i,上一个数的位置为last,我们先找出i在last后面的第一次出现的位置pos,最后一次出现的位置end
那么这一次会把last之后所有的排都抽一次,并且把在last之后的有数字i的牌都扔掉
接下来分两种情况:
①位置pos前面还有数字i:ans+=sum(last+1,n),last=0
②位置pos前面没有数字i:ans+=sum(last+1,end),last=end
其中sum(l,r)为位置[l,r]中还剩下的牌

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int MX = 1e5 + 5;struct BTree {    int sum[MX], Max;    BTree (){        Max=MX;        memset(sum,0,sizeof(sum));    }    inline int lowbit(int x) {        return x & (-x);    }    void add(int x, int val) {        while(x <= Max) {            sum[x] += val;            x += lowbit(x);        }    }    int tot(int x) {        int ret = 0;        while(x) {            ret += sum[x];            x -= lowbit(x);        }        return ret;    }    void clear() {        memset(sum, 0, sizeof(sum));    }    int query(int l, int r) {        if(l > r) return 0;        return tot(r) - tot(l - 1);    }}t;struct node{    int x,id;}a[MX];bool cmp(node p1,node p2){    if(p1.x!=p2.x) return p1.x<p2.x;    return p1.id<p2.id;}vector<int>v[MX];int main(){    int n;    //freopen("in.txt","r",stdin);    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&a[i].x),a[i].id=i;    sort(a+1,a+n+1,cmp);    int sz=0;    v[++sz].push_back(a[1].id);    for(int i=2;i<=n;i++) {        if(a[i].x!=a[i-1].x) ++sz;        v[sz].push_back(a[i].id);    }    for(int i=1;i<=n;i++) t.add(i,1);    int last=0;    LL ans=0;    for(int i=1;i<=sz;i++){        int pos=upper_bound(v[i].begin(),v[i].end(),last)-v[i].begin();        int cnt=v[i].size();        int bk=v[i][cnt-1];        if(pos>0) ans+=t.query(last,n);        else ans+=t.query(last+1,bk);        for(int j=cnt-1;j>=pos;j--){            t.add(v[i][j],-1);            v[i].pop_back();        }        if(pos>0) i--,last=0;        else last=bk==n?0:bk;    }    printf("%I64d\n",ans);    return 0;}


阅读全文
0 0