Problem Description
某天小Y家门前突然多出了两座石塔,这两座石塔妨碍了小X的出行,现在小X想要破坏这两座石塔,假设两座石塔分别由n1与n2块石头构成,每一块石头都有一个破坏顺序的优先级,并且保证这两座石塔中没有两块优先级一样的石头,小X觉得优先级越高的石头应该越早破坏掉,小X可以每次从任意一座石塔的塔顶移动一块石头到另外一座石塔的顶端,若此石头是所有石头中优先级最高的,则可以直接将其破坏而无需移动,问要破坏掉所有石头的最小移动次数是多少。
Input
第一行包含两个整数n1与n2,表示两座石塔的石头数,n1<=1e5,n2<=1e5
接下来n1行整数按照从顶到底的顺序给出第一座石塔石头的优先级,数字越大优先级越高
在接下来n2行按照同样格式给出第二座石塔石头的优先级
优先级范围1到n1+n2 且无重复。
没开64位WA了
#include<stdio.h>
#include<iostream>
using namespace std;
int n,a[2*100005]={0},c[2*100005]={0},loc[2*100005]={0};
int lowbit(int x)
{
return x&(-x);
}
void xq(int pos)
{
while(pos<=n)
{
c[pos]--;
pos+=lowbit(pos);
}
}
void add(int pos)
{
while(pos<=n)
{
c[pos]++;
pos+=lowbit(pos);
}
}
int sum(int p)
{
int sum=0;
while(p>0)
{
sum+=c[p];
p-=lowbit(p);
}
return sum;
}
int main()
{
int n1,n2,i,pos=0;
__int64 ans=0;
scanf("%d %d",&n1,&n2);
n=n1+n2;
loc[0]=n1;
loc[n1+n2+1]=n1;
pos=n1;
for(i=n1;i>=1;i--)
{
scanf("%d",&a[i]);
loc[a[i]]=pos--;
add(i);
}
pos=n1;
for(i=n1+1;i<=n1+n2;i++)
{
scanf("%d",&a[i]);
loc[a[i]]=++pos;
add(i);
}
if(loc[n1+n2]>n1)loc[n1+n2+1]=n1+1;
for(i=n1+n2;i>0;i--)
{
int tmp;
if(loc[i+1]>loc[i])tmp=sum(loc[i+1])-sum(loc[i]-1)-1;
else tmp=sum(loc[i])-sum(loc[i+1]-1)-1;
ans+=tmp;
xq(loc[i]);
}
printf("%I64d\n",ans);
return 0;
}