原题链接:https://www.luogu.org/problemnew/show/1327
题意简述:似乎不需要?反正就是一串数列任意交换两个数排序。
第一眼还以为是树状数组/归并排序求逆序对的裸题,然后仔细读题后发现可以任意交换,于是就想到了离散化解法。
自己独立写的第一个离散化,记录一下。
基本上就是每碰到一个错位的数,就交换一次,用一个数组来记录以来每个值都存在哪个位置上。
#include<cstdio> #include<algorithm> using namespace std; int n,ans,f[100005]; struct num { int a,b; }p[100005]; bool cmp(num x,num y) { return x.a<y.a; } bool cmp2(num x,num y) { return x.b<y.b; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&p[i].a); p[i].b=i; } sort(p,p+n,cmp); for(int i=0;i<n;i++) p[i].a=i; sort(p,p+n,cmp2); for(int i=0;i<n;i++) f[p[i].a]=i; for(int i=0;i<n;i++) { if(p[i].a!=i&&p[f[i]].a!=p[i].a) { ans++; int t=p[i].a,x=f[t]; p[i].a=p[f[i]].a; p[f[i]].a=t; f[t]=f[x]; f[i]=i; } } printf("%d",ans); return 0; }