7-11 最接近神的人 (80 分)
7-11 最接近神的人 (80 分),详细解答
破解了符文之语,小FF开启了通往地下的道路。当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案。而石门上方用古代文写着“神的殿堂”。小FF猜想里面应该就有王室的遗产了。但现在的问题是如何打开这扇门……
仔细研究后,他发现门上的图案大概是说:古代人认为只有智者才是最容易接近神明的。而最聪明的人往往通过一种仪式选拔出来。仪式大概是指,即将隐退的智者为他的候选人写下一串无序的数字,并让他们进行一种操作,即交换序列中相邻的两个元素。而用最少的交换次数使原序列变成不下降序列的人即是下一任智者。
小FF发现门上同样有着n个数字。于是他认为打开这扇门的秘诀就是找到让这个序列变成不下降序列所需要的最小次数。但小FF不会……只好又找到了你,并答应事成之后与你三七分……
输入格式:
第一行为一个整数n,表示序列长度
第二行为n个整数,表示序列中每个元素。
输出格式:
一个整数ans,即最少操作次数。
输入样例:
4
2 8 0 3
输出样例:
3
说明/提示:
对于30的数据1≤n≤10
4
。
对于100的数据1≤n≤5∗10
5
;
−maxlongint≤A[i]≤maxlongint。
样例说明:开始序列为2803,目标序列为0238,可进行三次操作的目标序列:
1.Swap (8,0):2 0 8 3
2.Swap (2,0):0 2 8 3
3.Swap (8,3):0 2 3 8
#include <iostream>
using namespace std;
int n;
int a[500010];
long long maxx;///逆序对的个数 注意 最后结果必须是long long型,并在全局中 ,或者将merge1函数改为 long long 型 最后返回得到的也才是long long型
void merge_sort(int left,int right)
{
int sum=0;
if(left>=right)
return;
int mid=left+(right-left)/2;
int b[right-left+1],idx=0,i=left,j=mid+1;
while(i<=mid&&j<=right)
{
if(a[i]<=a[j])
b[idx++]=a[i++];
else
{
maxx+=(mid-i+1);
b[idx++]=a[j++];
}
}
while(i<=mid)
b[idx++]=a[i++];
while(j<=right)
b[idx++]=a[j++];
for(i=left,j=0;i<=right&&j<idx;i++,j++)
a[i]=b[j];
}
int merge1(int left,int right)
{
if(left>=right)
return 0;
merge1(left,left+(right-left)/2);
merge1(left+(right-left)/2+1,right);
merge_sort(left,right);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
merge1(1,n);
cout<<maxx<<endl;
return 0;
}
202204021434六