题目大意:给你一堆n张牌(数字可以相同),你只能从上面取牌,如果是当前牌堆里面最小的值则拿走,
否则放到底部,问你一共要操作多少次。
思路:讲不清楚,具体看代码。。
#include<bits/stdc++.h> #define pb push_back #define ll long long using namespace std; const int N=1e5+5; ll n,mxi[N],a[N];//a[i]保存原始数据,mxi[i]保存大小为i的牌最下面一张的编号 vector<ll> p[N];//p[i] 保存值为i的所有牌的编号,从小到大。 ll solve() { sort(a+1,a+n+1);//先从小到大排序 ll now_n=n;//now_n表示到目前为止还剩多少张牌 ll ans=now_n;//第一次操作取全部牌,扔掉大小为a[1]的。 now_n-=p[a[1]].size(); p[a[1]].clear(); for(int i=2;i<=n;i++)//从a[2]开始 { if(p[a[i]].empty()) continue;//如果这个大小的都取完了跳过。 if(p[a[i]].back()>mxi[a[i-1]])//如果当前a[i]的最底下一个的编号大于 { //a[i-1]最底下的编号,则在mxi[a[i-1]]下面的编号 //在上一次取a[i-1]的时候就取掉了。 vector<ll> ::iterator it; it=lower_bound(p[a[i]].begin(),p[a[i]].end(),mxi[a[i-1]]); ll num=p[a[i]].end()-it; p[a[i]].erase(it,p[a[i]].end()); if(!p[a[i]].empty()) mxi[a[i]]=p[a[i]].back(); now_n-=num;//减掉num为当前的牌数。 } else//取出全部牌将a[i]大小的牌扔掉。 { ans+=now_n; now_n-=p[a[i]].size(); p[a[i]].clear(); } } return ans; } int main() { cin>>n; for(int i=1;i<=n;i++) { scanf("%I64d",&a[i]); p[a[i]].pb(i); mxi[a[i]]=i; } ll ans=solve(); cout<<ans<<endl; return 0; }