Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 52097 | Accepted: 19113 |
Description
Input
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
Source
之前写过求逆序数的树状数组的方法和归并排序的方法
感觉逆序数这玩意就应该用归并排序做啊~~
说线段树的方法:与上一篇
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 500005 struct node { int id,val; }num[maxn]; bool cmp(node n1,node n2) { return n1.val<n2.val; } struct Tree { int l,r,tot; }tree[maxn<<2]; int rank[maxn]; void build(int rt,int l,int r) { tree[rt].l=l;tree[rt].r=r; tree[rt].tot=0; if(l==r)return; int mid=(l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update(int rt,int x) { tree[rt].tot++; if(tree[rt].l==tree[rt].r&&tree[rt].l==x) return; int mid=(tree[rt].l+tree[rt].r)/2; if(x<=mid)update(rt<<1,x); else update(rt<<1|1,x); } int query(int rt,int l,int r) { int sum=0; if(tree[rt].l==l&&tree[rt].r==r) return tree[rt].tot; int mid=(tree[rt].l+tree[rt].r)/2; if(r<=mid) sum=query(rt<<1,l,r); else if(l>mid) sum=query(rt<<1|1,l,r); else sum=query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r); return sum; } int main() { // freopen("cin.txt","r",stdin); int n; while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) { scanf("%d",&num[i].val); num[i].id=i; } sort(num,num+n,cmp); for(int i=0;i<n;i++) rank[num[i].id]=i+1; build(1,0,n+1); long long sum=0; for(int i=0;i<n;i++) { int x = rank[i]; sum+=query(1,x+1,n+1); update(1,x); } printf("%I64d\n",sum); } return 0; }