Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 52778 | Accepted: 19348 |
Description

Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
题意:给一组数,每次只能交换相邻两个数的位置,问最少交换多少次,使得这个序列从小到大排序;
题解:求逆序数的对数
线段树:
#include<stdio.h> #include<string.h> #include<algorithm> #define LL long long #define MAX 500500 using namespace std; int n,m; struct node { int val,pos; }num[MAX]; int sum[MAX<<2]; void pushup(int o) { sum[o]=sum[o<<1]+sum[o<<1|1]; } void gettree(int o,int l,int r) { sum[o]=0; if(l==r) return ; int mid=(l+r)>>1; gettree(o<<1,l,mid); gettree(o<<1|1,mid+1,r); pushup(o); } void update(int o,int l,int r,int pos) { if(l==r) { sum[o]+=1; return ; } int mid=(l+r)>>1; if(pos<=mid) update(o<<1,l,mid,pos); else update(o<<1|1,mid+1,r,pos); pushup(o); } int find(int o,int l,int r,int L,int R) { if(L<=l&&R>=r) return sum[o]; int mid=(l+r)>>1; int ans=0; if(L<=mid) ans+=find(o<<1,l,mid,L,R); if(R>mid) ans+=find(o<<1|1,mid+1,r,L,R); return ans; } bool cmp(node a,node b) { if(a.val!=b.val) return a.val<b.val; else return a.pos<b.pos; } int main() { int j,i,t,k; while(scanf("%d",&n),n) { gettree(1,1,n); for(i=1;i<=n;i++) { scanf("%d",&num[i].val); num[i].pos=i; } sort(num+1,num+1+n,cmp); LL ant=0; for(i=1;i<=n;i++) { update(1,1,n,num[i].pos); ant+=i-find(1,1,n,1,num[i].pos); } printf("%lld ",ant); } return 0; }
树状数组:
#include<stdio.h> #include<string.h> #include<algorithm> #define LL long long #define MAX 500500 using namespace std; int n,m; int c[MAX<<1]; struct node { int val,pos; }num[MAX]; bool cmp(node a,node b) { if(a.val!=b.val) return a.val<b.val; else return a.pos<b.pos; } void update(int x) { while(x<=n) { c[x]+=1; x+=x&-x; } } LL sum(int x) { LL ans=0; while(x>=1) { ans+=c[x]; x-=x&-x; } return ans; } int main() { int j,i,t,k; while(scanf("%d",&n),n) { for(i=1;i<=n;i++) { scanf("%d",&num[i].val); num[i].pos=i; } sort(num+1,num+n+1,cmp); memset(c,0,sizeof(c)); LL ant=0; for(i=1;i<=n;i++) { update(num[i].pos); ant+=i-sum(num[i].pos); } printf("%lld ",ant); } return 0; }