Luogu1966 火柴排队
思路很妙qwq
使 \(\sum_{i = 1}^{n}(a_{i} - b_{i})^{2}\) 最小,那么使 \((a_{i} - b_{i})\) 最小即可。
显然要使排序后 \(A\) 与 \(B\) 第\(i\)大的元素相对应。
离散化 \(A,B\) ,移动次数就是以 \(A\) 的位置为基准时 \(B\) 的逆序对个数。归并排序。
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#define mod 99999997
using namespace std;
struct node{
int num, id;
}hc1[1000001], hc2[1000001];
int n, ans;
int a[1000001], b[1000001];
bool cmp(node x, node y){
return x.num<y.num;
}
inline int read(){
int f=1, x=0;
char ch=getchar();
for(;!isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
for(; isdigit(ch); ch=getchar()) x=x*10+ch-48;
return x*f;
}
void merge_sort(int l, int r){
if(l>=r)return;
int mid=(l+r)>>1;
merge_sort(l, mid);
merge_sort(mid+1, r);
int i=l, j=mid+1, k=l;
while(i<=mid&&j<=r){
if(a[i]>a[j]){
b[k++]=a[j++];
ans+=mid-i+1;
ans%=mod;
}
else b[k++]=a[i++];
}
while(i<=mid)b[k++]=a[i++];
while(j<=r)b[k++]=a[j++];
for(int i=l; i<=r; i++)
a[i]=b[i];
}
int main(){
n=read();
for(int i=1; i<=n; i++)
hc1[i].num=read(), hc1[i].id=i;
for(int i=1; i<=n; i++)
hc2[i].num=read(), hc2[i].id=i;
sort(hc1+1, hc1+n+1, cmp);
sort(hc2+1, hc2+n+1, cmp);
for(int i=1; i<=n; i++)
a[hc1[i].id]=hc2[i].id;
merge_sort(1, n);
printf("%d", ans);
return 0;
}
不如吃茶去