题目链接
思路:考虑一下每个数被取时候和前一个被取得数之间的贡献,比如12 2 2 10 12 1,很明显10这个是肯定是12取完之后再取10,我们只有知道2和10之间有多少数比10大就行了,如果2的位置在10的右边也很好算,就是总数减去2到10中间的那块就行了,比如2和1,只要总数-【2的位置,1的位置】比2大的数就可以了,可是这里这么算有一个前提,就是你的知道这n个数被取时候的顺序才行,,比如n个数不相同那很好办,比较麻烦的就是相同的数了,这里比方说上面的那个例子,有2个12,那么究竟是那一个12先取呢?很明显就是在12之前取得也就是10的后面依次取,所以是下标为5的12先取,再是下标为1的,这个模拟一次就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lowbit(i) (i)&(-i)
const int maxn=1e5+1;
int c[maxn];
pair<int,int>p[maxn];
set<int>s;
vector<int>v[maxn];
void update(int x,int v)
{
while(x<maxn) c[x]+=v,x+=lowbit(x);
}
ll query(int x)
{
ll res=0;
while(x>0) res+=c[x],x-=lowbit(x);
return res;
}
bool cmp1(const pair<int,int>&a,const pair<int,int>&b)
{
return a.first==b.first?a.second<b.second:a.first<b.first;
}
bool cmp2(const pair<int,int>&a,const pair<int,int>&b)
{
return a.first==b.first?a.second>b.second:a.first>b.first;
}
int main()
{
int n,minn=0,temp=0;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&p[i].first),p[i].second=i;
sort(p+1,p+1+n,cmp1);
for(int i=1;i<=n;++i)
{
if(p[i].first!=p[i-1].first)
{
minn=temp%n;
temp=0;
}
if(p[i].second<minn) p[i].second+=n;
temp=max(temp,p[i].second);
}
sort(p+1,p+1+n,cmp2);
for(int i=1;i<=n;++i) if(p[i].second>n) p[i].second-=n;
//for(int i=1;i<=n;++i) cout<<p[i].first<<" "<<p[i].second<<endl;
ll ans=0;update(p[1].second,1);
for(int i=2;i<=n;++i)
{
if(p[i].second>p[i+1].second) ans+=query(p[i].second)-query(p[i+1].second);
else ans+=query(n)-(query(p[i+1].second)-query(p[i].second-1));
update(p[i].second,1);
}
printf("%lld\n",ans+n);
}