题目大意就是要求数组中逆序数的对数,和51nod1019一样,可以用树状数组。
先对所有数进行排序,还要记录每个数原来在数组中的下标,在排好序的数组中,从小到大依次访问,假设访问到第i个数,用树状数组查询1~i-1的数中原始下标小于等于k的个数(k是第i个数的原始下标)。
同时动态更新树状数组。
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int C[500005],n; int lowbit(int x) { return x&-x; } int sum(int x) //求前缀和,x向左上爬 { int ret=0; while(x>0) { ret+=C[x]; x-=lowbit(x); } return ret; } void add(int x,int d) //A[x]加上d,x向右上爬 { while(x<=n) { C[x]+=d; x+=lowbit(x); } } struct D { int id; long long val; }; bool operator < (D a,D b) { return a.val<b.val; } D data[500005]; int main() { while(cin>>n&&n) { long long ans=0; for(int i=1; i<=n; i++) { cin>>data[i].val; data[i].id=i; } sort(data+1,data+n+1); data[0].val=-111; memset(C,0,sizeof(C)); int pre; for(int i=1; i<=n; i++) { if(data[i].val!=data[i-1].val) { pre=sum(n)-sum(data[i].id); ans+=pre; } else ans+=pre; add(data[i].id,1); } cout<<ans<<endl; } }