原题地址:http://poj.org/problem?id=1804
输入:输入T代表T组数据,每行输入n代表数据的量,然后输入数据。
输出:输出逆序对数。
用树状数组,每次插入一个数就更新一次C数组,即使C[i]+1然后一直向上更新到max。然后sum(i)统计小于等于i的数量,i-sum(i)则求的是大于i的数据,再遍历一遍即可。
由于数据范围 [-1000000, 1000000],所以离散化数据,这里用的结构体离散化。具体代码看如下
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; const int maxn=1000005; int c[maxn]; int n,l,r,max1,kk[maxn]; struct a{ int x; int y; int z; }; struct a num[maxn]; int lowbit(int x){ return x&-x; } int update(int x){ while(x<=max1){ ++c[x]; x+=lowbit(x); } return 0; } int sum(int x){ int ans=0; while(x>0){ ans+=c[x]; x-=lowbit(x); } return ans; } bool cmp(a q,a w){ return q.x<w.x; } int main(){ int T; cin>>T; int x,y; int count=1; char flag; while(T--){ int ans=0; memset(kk,0,sizeof(kk)); memset(c,0,sizeof(c)); cin>>n; //离散化 for(int i=1;i<=n;i++) { cin>>num[i].x; num[i].y=i; } sort(num+1,num+n+1,cmp); num[1].z=1; for(int i=2;i<=n;i++){ if(num[i].x==num[i-1].x) num[i].z=num[i-1].z; else num[i].z=num[i-1].z+1; } for(int i=1;i<=n;i++){ kk[num[i].y]=num[i].z; } //kk数组为离散化后结果 for(int i=1;i<=n;i++) max1=max(max1,kk[i]); for(int i=1;i<=n;i++) { update(kk[i]); ans+=i-sum(kk[i]); } cout<<"Scenario #"<<count<<":"<<endl; cout<<ans; cout<<endl<<endl; count++; } return 0; }