当前位置: 代码迷 >> 综合 >> bzoj4989: [Usaco2017 Feb]Why Did the Cow Cross the Road
  详细解决方案

bzoj4989: [Usaco2017 Feb]Why Did the Cow Cross the Road

热度:39   发布时间:2023-10-29 12:25:27.0

题意

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;
}
  相关解决方案