题解:P12890 [蓝桥杯 2025 国 Java B] 道具摆放
P12890 [蓝桥杯 2025 国 Java B] 道具摆放题解
前置芝士:逆序对求解方法。\ 不会的先去这里。
题意
给一个
思路
相当于将排列变成升序。
每交换一次就会至多减少一个逆序对,所以至少需要交换的次数为逆序对数量,可以使用树状数组或归并排序来实现。我这里使用好写的树状数组。
求出逆序对数量
-
-
- 否则不可能,因为上面两种情况可以和更大的
m 的倍数一样,输出-1 。
然后呢?没了?确实。
代码
清晰的思路,简洁的树状数组。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[500010],c[500010];
int cnt;
int lowbit(int x){return x&(-x);}
int que(int x){int re=0;while(x>0)re+=c[x],x-=lowbit(x);return re;}
void upd(int x,int d){while(x<=n)c[x]+=d,x+=lowbit(x);}
signed main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=n;i;i--) cnt+=que(a[i]-1),upd(a[i],1);
int f=(cnt+m-1)/m;
if(f*m%2==cnt%2) printf("%lld",f*m);
else if((f+1)*m%2==cnt%2) printf("%lld",(f+1)*m);
else printf("-1");
}