CF 362C 冒泡排序 交换哪两个数逆序数减少最多
来源:互联网 发布:windows api 怎么使用 编辑:程序博客网 时间:2024/06/07 13:18
交换两个数,求使得排列的逆序数最多减少多少,以及有多少个这样的数对
数据范围有5000,我的算法是n^2logn
因为有n^2个询问,所以最好O(1)的回答,所以需要先预处理一下。
怎样快速回答交换两个数之后逆序数的改变呢?
这就要快速的算出i和j之间有多少个比num[i]小的数,有多少个比num[j]小的数,比它们大的数一减就OK。
设 si为i到j中比i小的数 bi为比i大的数 sj为比j小的数,bj为比j大的数。
所以逆序数减少量为旧逆序数-新逆序数=si-bi+bj-sj-1 最后那个1是指i和j交换后减少的逆序数。
#include<stdio.h>#include<string.h>int res[5200][5200];//到i为止小于num[j]的数字int bit[5200],n;int num[5200];int sum(int i){int s=0;while(i>0){s+=bit[i];i -= i & -i;}return s;}void add(int i,int x){while(i<=n){bit[i]+=x;i += i & -i;}}int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);num[i]++;}memset(bit,0,sizeof(bit));memset(res,0,sizeof(res));int tot=0;for(int i=1;i<=n;i++){add(num[i],1);for(int j=1;j<=n;j++){if(num[j]==0) continue;res[i][j]=sum(num[j]-1);}if(num[i]==0) continue;tot+=(i-sum(num[i]));}int max_=-1;int ans=0;for(int i=1;i<n;i++){for(int j=i+1;j<=n;j++){if(num[i]>num[j]){int tn=j-i-1;int si=res[j][i]-res[i][i];int bi=tn-si;int sj=res[j][j]-res[i][j];int bj=tn-sj;int t=si-bi+bj-sj-1;if(t>max_){max_=t;ans=1;}else if(t==max_){ans++;}}}}printf("%d %d\n",tot-max_,ans);}
- CF 362C 冒泡排序 交换哪两个数逆序数减少最多
- 178_冒泡排序的交换次数(逆序数)
- 冒泡排序以及两个数之间的交换
- C语言-交换两个数
- c语言两个数交换
- C 指针交换两个数
- 【C语言】交换两个数
- C语言交换两个数
- C语言两个数交换
- 冒泡排序(优化版)的比较次数和交换数字次数 逆序数+树状数组
- 2299-Ultra-QuickSort-交换相邻两个数排序-求逆序对个数-合并排序
- C语言指针应用--互换两个数&冒泡排序
- Codeforces 414C Mashmokh and Reverse Operation 归并排序在线求交换序列后逆序数
- C语言实现交换两个数
- c c++ 交换两个数的值
- c语言--交换两个数的函数
- C语言交换两个数的值
- 【C语言】交换两个数的内容
- IOS7使用Audio Queue同时进行录音和播放
- 技术团队新官上任之高层篇
- css3中position定位详解
- cocos2d-x节点(base64.h)API
- Linux 上不可修改的文件和目录
- CF 362C 冒泡排序 交换哪两个数逆序数减少最多
- 技术团队新官上任之中层篇
- GridView事件说明及执行顺序
- 技术团队新官上任之基层篇
- cocos2d-x节点(CCIMEDispatcher.h)API
- 写给大家看的设计书 (第3版)
- ORA-27102: out of memory Linux-X86_64 Error: 28: No space left on device (Doc ID 301830.1)
- cocos2d-x节点(CCTextureAtlas.h)API
- cocos2d-x节点(CCTextureCache.h)API