poj_2299_Ultra-QuickSort
来源:互联网 发布:第四类接触知乎 编辑:程序博客网 时间:2024/06/01 13:55
线段树,树状数组,归并排序入门好题.
在此给出三种算法的入门讲解.
题目大意:
给出一个序列,求这个序列的逆序数有多少.意思就是给一个序列,对于序列中的每一位,前面有多少位大于它的数.求这些个数的合.这个序列一共最多有n < 500,000个数.
解题思路:
基本问题就是统计每一位前面大于它的数.因为每个数0 ≤ a[i] ≤ 999,999,999 ,而总数只有500,000,所以如果用线段树或树状数组做需要排序后离散化.
离散化:
对于一组十个数的离散化:
Number
1
10
100
200
45
78
10
63
85
900
Id
1
2
3
4
5
6
7
8
9
10
先对数组排序由ID抽象出新的序列数字,得出新的个数时要注意,当原个数相同时,新个数也要相同,同时下一个数的值等于它的位置N:
New n
1
2
2
4
5
6
7
8
9
10
Old n
1
10
10
45
63
78
85
100
200
900
Id
1
2
7
5
8
6
9
3
4
10
原序列就转化为:
Number
1
10
100
200
45
78
10
63
85
900
New n
1
2
8
9
4
6
2
5
7
10
由此方法可将这道题数据范围缩小至500000;
离散化结束后就可以求每一个数前面比其小的数的个数了.
源代码-树状数组:
#include <iostream>#include <cstdio>#include <cstring>#include <climits>using namespace std;const int N=500010;typedef struct _data{int id;int num;}data;int n;int b[N],c[N];long long ans;data a[N];int cmp(const void *a,const void *b){return ((data *)a)->num - ((data *)b)->num;}void init(){ans=0;memset(b,0,sizeof(b));memset(c,0,sizeof(c));int i;for(i=1;i<=n;i++)scanf("%d",&a[i].num),a[i].id=i;qsort(a+1,n,sizeof(a[0]),cmp);b[a[1].id]=1;for(i=2;i<=n;i++)if(a[i].num!=a[i-1].num)b[a[i].id]=i;elseb[a[i].id]=b[a[i-1].id];}inline int lowbit(int x){return x&(-x);}void updata(int x,int k){for(int i=x;i<=n;i+=lowbit(i))c[i]+=k;}int getsum(int x){int sum=0;for(int i=x;i>0;i-=lowbit(i))sum+=c[i];return sum;}int main(){while(scanf("%d",&n),n){init();for(int i=1;i<=n;i++){updata(b[i],1);ans+=(getsum(n)-getsum(b[i]));}printf("%lld\n",ans);}return 0;}
源代码-线段树:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define ROOT 1,n,1#define LSON l,m,rt<<1#define RSON m+1,r,rt<<1|1const int N=500010;typedef struct _sArray{int x,id;}sArray;int n,a[N],c[N<<2];sArray b[N];int cmp(const void *a,const void *b){return ((sArray *)a)->x - ((sArray *)b)->x;}inline void pushUp(int rt){c[rt]=c[rt<<1]+c[rt<<1|1];}void build(int l,int r,int rt){c[rt]=0;if(l==r)return ;int m=(l+r)>>1;build(LSON);build(RSON);pushUp(rt);}void init(){int i;for(i=1;i<=n;i++){scanf("%d",&b[i].x);b[i].id=i;}qsort(b+1,n,sizeof(b[0]),cmp);a[b[1].id]=1;for(i=2;i<=n;i++){if(b[i-1].x==b[i].x)a[b[i].id]=a[b[i-1].id];elsea[b[i].id]=i;}memset(c,0,sizeof(c));build(ROOT);}void upData(int q,int l,int r,int rt){if(l==r){c[rt]++;return ;}int m=(l+r)>>1;if(q<=m)upData(q,LSON);elseupData(q,RSON);pushUp(rt);}long long getSum(int L,int R,int l,int r,int rt){if(L<=l&&r<=R)return c[rt];int m=(l+r)>>1;long long ret=0;if(L<=m)ret+=getSum(L,R,LSON);if(R>m)ret+=getSum(L,R,RSON);return ret;}void word(){int i;long long ans=0;for(i=1;i<=n;i++){upData(a[i],ROOT);ans+=getSum(a[i]+1,n,ROOT);}printf("%lld\n",ans);}int main(){while(scanf("%d",&n),n){init();word();}return 0;}
- poj_2299_Ultra-QuickSort
- POJ_2299_Ultra-QuickSort
- POJ_2299_Ultra-QuickSort & NYOJ_117_求逆序数
- poj_2299_Ultra-QuickSort_201407251113
- Quicksort
- QuickSort
- quicksort
- quicksort
- QuickSort
- QuickSort
- QuickSort
- QuickSort
- QuickSort
- QuickSort
- quicksort
- QuickSort
- QuickSort
- QuickSort
- 很久没写代码了
- 通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connecti...
- 解析STM32启动过程
- Win7+MySql,opentaps安装
- C++调用JAVA方法详解_____转载自http://public0821.iteye.com/blog/423941
- poj_2299_Ultra-QuickSort
- 在 Ubuntu 上搭建 git 仓库服务器 gitolite
- 字符串
- zk笔记--使用java客户端访问
- 最全的软件测试工具LR中性能数据翻译(一)
- 不错的blog
- HandlerThread 之于Thread区别以及使用规则
- 字符串分割成二维数组,或加入到Map中
- 《文献管理与信息分析•网络班》报名