1. 程式人生 > 其它 >Cards Sorting(樹狀陣列+更具題目的特定優化)

Cards Sorting(樹狀陣列+更具題目的特定優化)

思路:將同樣大小的數為一組,這一組的某個特定值的位置,來更新ans。

特定值:last的左邊的值的優先順序高於右邊的值的優先順序。

樹狀陣列維護這個區間裡面有多少個沒有被刪的值。

B. 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 100000, 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 ≤ 100000) — the number of cards in the deck. The second line contains a sequence of n integers a1, a2, ..., an (1 ≤ ai ≤ 100000), 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 ———————————————— 版權宣告:本文為CSDN博主「Mitsuha_」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。 原文連結:https://blog.csdn.net/Mitsuha_/article/details/78448537
View problem
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define M 100005

template <class G> void read(G &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return ;
 } 
 
int n;
vector <int> p[M];
int c[M];
int qu(int a)
{
    int res=0;
    while(a>0)
    {
        res+=c[a];
        a-=(a&-a);
    }
    return res;
}
void up(int a,int b)
{
    while(a<=n)
    {
        c[a]+=b;
        a+=(a&-a);
    }
}
int main(){
    
    read(n);
    for(ri i=1;i<=n;i++) 
    {
        int a;read(a);
        p[a].push_back(i);
    }
    int last=0;long long ans=0;
    for(ri i=1;i<=n;i++)
    {
        up(i,1);
    }
    for(ri i=1;i<=100000;i++)
    {
        int m=p[i].size();if(!m) continue;
        int tmp=-1;
        for(ri j=0;j<p[i].size();j++)
        {
            int b=p[i][j];
            if(b<last)
            {
                tmp=b;
            }
        }
        if(tmp==-1)
        {
            ans+=qu(p[i][p[i].size()-1])-qu(last);
            last=p[i][p[i].size()-1];
        }
        else
        {
            ans+=qu(n)-qu(last-1)+qu(tmp); // attention last-1 very important
            last=tmp;
        }
        for(ri j=0;j<p[i].size();j++)
        {
            int b=p[i][j];
            up(b,-1);
        }
    }
    printf("%lld",ans);
    return 0;
}
View Code