听说树状数组又短又快,于是刷了一道。看完1~5,擦,神题呀!一看6.。。。
首先把2堆顶和顶对起来,转换成数组,记录左堆顶,然后从最大的开始拿,每次用树状数组得到需要的步数。细节还是蛮多的。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100005],b[100005],c[100005],n1,n2,l;
long long Ans;
bool cmp(int x,int y)
{
return a[x]>a[y];
}
void del(int t)
{
for (;t<=n2;t+=t&(-t)) c[t]--;
}
int qry(int t)
{
int sum=0;
for (;t;t-=t&(-t)) sum+=c[t];
return sum;
}
int main()
{
scanf("%d%d",&n1,&n2);
for (int i=n1;i>=1;i--)
scanf("%d",&a[i]);
for (int i=n1+1;i<=n1+n2;i++)
scanf("%d",&a[i]);
n2=n1+n2;
for (int i=1;i<=n2;i++)
b[i]=i;
sort(b+1,b+n2+1,cmp);
for (int i=1;i<=n2;i++)
c[i]=i&(-i);
for (int i=1;i<=n2;i++)
{
l=qry(b[i])-qry(n1);
if (l>0) Ans+=l-1; else Ans+=-l;
n1=b[i]-1; del(b[i]);
}
printf("%lld\n",Ans);
return 0;
}