poj 2299 Ultra-QuickSort(求逆序对)
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
题意:给一组数,每次只能交换相邻两个数的位置,问最少交换多少次,使得这个序列从小到大排序;
题解:求逆序数的对数
线段树:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #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\n" ,ant); } return 0; } |
树状数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #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\n" ,ant); } return 0; } |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步