【题目描述】:
破解了符文之语,小FF开启了通往地下的道路。当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案。而石门上方用古代文写着“神的殿堂”。小FF猜想里面应该就有王室的遗产了。但现在的问题是如何打开这扇门……
仔细研究后,他发现门上的图案大概是说:古代人认为只有智者才是最容易接近神明的。而最聪明的人往往通过一种仪式选拔出来。仪式大概是指,即将隐退的智者为他的候选人写下一串无序的数字,并让他们进行一种操作,即交换序列中相邻的两个元素。而用最少的交换次数使原序列变成不下降序列的人即是下一任智者。
小FF发现门上同样有着n个数字。于是他认为打开这扇门的秘诀就是找到让这个序列变成不下降序列所需要的最小次数。但小FF不会……只好又找到了你,并答应事成之后与你三七分……
【输入描述】:
第一行,一个数n,表示序列中有n个数。
第二行n个数,表示给定的序列。
【输出描述】:
给定序列的最少操作次数。
【样例输入】:
6
5 4 2 6 3 1
【样例输出】:
11
【时间限制、数据范围及描述】:
时间:1s 空间:128M
对于50%的数据,n<=2500
对于100%的数据,n<=40000。
-maxlongint<=ai<=maxlongint
树状数组求逆序对个数,求逆序对个数去年这个时候就写过,不过当时没有过,苦于没有数据,所以一直拖着,现在终于搞定了
当时的错误:当时没有判断序列中有相同数的情况
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <iostream> 9 #include "algorithm" 10 using namespace std; 11 typedef long long LL; 12 const int MAX=40005; 13 int n; 14 int c[MAX]; 15 struct Node{ 16 LL w; 17 int p,z; 18 }vv[MAX]; 19 bool cmp1(Node x,Node y){return x.w>y.w;} 20 bool cmp2(Node x,Node y){return x.p<y.p;} 21 void add(int x,int y){for (;x<MAX;c[x]+=y,x+=(x&-x));} 22 int search(int x){int an(0);for (;x>0;an+=c[x],x-=(x&-x));return an;} 23 void init(){ 24 int i,j; 25 scanf("%d",&n); 26 for (i=1;i<=n;i++){ 27 scanf("%lld",&vv[i].w); 28 vv[i].p=i; 29 } 30 sort(vv+1,vv+n+1,cmp1); 31 int tt=0; 32 for (i=1;i<=n;i++){ 33 if (vv[i].w!=vv[i-1].w) 34 vv[i].z=++tt; 35 else 36 vv[i].z=tt; 37 } 38 sort(vv+1,vv+n+1,cmp2); 39 memset(c,0,sizeof(c)); 40 } 41 int main(){ 42 init();int i,j; 43 int ans=0; 44 for (i=1;i<=n;i++){ 45 ans+=search(vv[i].z-1); 46 add(vv[i].z,1); 47 } 48 printf("%d",ans); 49 return 0; 50 }