题意
bzoj有中文翻译了。。
要注意一下就是只能选择一个串翻
题解
先算出原来的代价
然后暴力算一下,环掉第1位的代价
然后把第一位换掉就好了
然后两个数组交换再做一次
但是答案很大。。
要开LL,并且一开始我的最大值还弄小了QAQ
#include<cstdio>
#include<cstring>
typedef long long LL;
const LL N=100005;
LL n;
LL ans=1LL<<55;
LL mymin (LL x,LL y){return x<y?x:y;}
LL pos[N];//表示这个数字在b里面的下标
LL f[N];//树状数组
LL lb (LL x){return x&(-x);}
LL get (LL x)
{
LL lalal=0;
while (x>=1)
{
lalal=lalal+f[x];
x-=lb(x);
}
return lalal;
}
void add (LL x)
{
while (x<=n)
{
f[x]++;
x+=lb(x);
}
}
void solve (LL a[],LL b[])
{
memset(f,0,sizeof(f));
for (LL u=1;u<=n;u++) pos[b[u]]=u;
LL cnt=0;
for (LL u=1;u<=n;u++)//加入谁
{
cnt=cnt+(u-1)-get(pos[a[u]]-1);
add(pos[a[u]]);
}
ans=mymin(ans,cnt);
for (LL u=1;u<=n;u++)//把谁移走
{
cnt=cnt-(pos[a[u]]-1)+(n-pos[a[u]]);
ans=mymin(ans,cnt);
}
}
int main()
{
LL a[N],b[N];
scanf("%lld",&n);
for (LL u=1;u<=n;u++) scanf("%lld",&a[u]);
for (LL u=1;u<=n;u++) scanf("%lld",&b[u]);
solve(a,b);solve(b,a);
printf("%lld\n",ans);
return 0;
}