树状数组---逆序类题目
来源:互联网 发布:sql server和mysql区别 编辑:程序博客网 时间:2024/04/28 15:48
1. POJ 2299 Ultra-QuickSort(树状数组逆序+离散化)
题目链接:http://poj.org/problem?id=2299
题意: 给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该序列为递增序列?
题解:其实就是求逆序对的数量。可以用树状数组来求。虽然数的大小为 999,999,999,但是数的规模只有500,000,所以可以对数据进行离散化,之后就可以用树状数组来求了。
代码:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAX=500000+5;typedef long long LL;int bit[MAX];int a[MAX];int tmp[MAX];int N;int sum(int x){ int sum=0; while(x>0) { sum+=bit[x]; x-=(x&(-x)); } return sum;}void add(int x,int value){ while(x<=N) { bit[x]+=value; x+=(x&(-x)); }}int main(){ int n; while(scanf("%d",&n)&&n) { memset(bit,0,sizeof(bit)); for(int i=0;i<n;i++) { scanf("%d",&a[i]); tmp[i]=a[i]; } N=n; sort(tmp,tmp+n); for(int i=0;i<n;i++) { a[i]=lower_bound(tmp,tmp+n,a[i])-tmp+1; } LL ans=0; for(int i=n-1;i>=0;i--) { ans=ans+sum(a[i]); add(a[i],1); } cout<<ans<<endl; } return 0;}
2.HDU 1394 Minimum Inversion Number(树状数组逆序)
题目链接:点击打开链接
题意:给定一个序列,对该序列的n种排列(排列如下)的每种排列的逆序数求最大值:
a1, a2, ..., an-1, an
a2, a3, ..., an, a1
a3, a4, ..., an, a1, a2
...
an, a1, a2, ..., an-1
题解:
我们可以分为n步,每次都将第一个元素移动到最后一个,这样原来的逆序对变为顺序对,原来的顺序对变为逆序对,所以逆序对减少的数量为(比他小的数的个数)减去(比他大的数的个数),即cnt-(n-1-cnt)=2*cnt-n+1,cnt为比当前数小的数,cnt可以用树状数组求出,但是因为每次操作的都是第一个数,并且数只有1-n,所以cnt就等于a[i]-1。cnt-(n-1-cnt)=2*cnt-n+1=2*a[i]-n-1。进行n步求出逆序对减少的数量的最大值用总的逆序对数减去这个值即可。
代码:
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>using namespace std;const int MAX=5000+5;const int INF=0x3f3f3f3f;typedef long long LL;int a[MAX];int rs[MAX];int bit[MAX];int N;int sum(int x){ int s=0; while(x>0) { s+=bit[x]; x-=(x&(-x)); } return s;}void add(int x,int v){ while(x<=N) { bit[x]+=v; x+=(x&(-x)); }}int main(){ int n; while(scanf("%d",&n)!=EOF) { memset(bit,0,sizeof(bit)); N=n; int tol=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); a[i]++; tol+=sum(N)-sum(a[i]); add(a[i],1); } int mmax=0; int cur=0; for(int i=0;i<n-1;i++) { /* int cnt=sum(a[i]-1); cur+=cnt-(n-1-cnt);*/ cur+=2*a[i]-n-1; mmax=max(mmax,cur); } printf("%d\n",tol-mmax); } return 0;}
0 0
- 树状数组---逆序类题目
- HDOJ 题目2838 Cow Sorting(树状数组逆序对)
- 树状数组逆序对
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 求逆序数(树状数组)
- 树状数组之逆序数
- kafkaSpout工作流程简介
- 【zzuliOJ】1909 - 小火山的友情距离(数学)
- Android酷炫实用的开源框架(UI框架)
- [HDU 5819] Knights (稍难的概率DP)
- Android编程之fill_parent、wrap_content和match_parent的区别
- 树状数组---逆序类题目
- maven package用法 打包maven项目
- 树状数组题目---HDU 1541 stars 及其变形(降维思想)
- iOS coreBluetooth编程中需要注意的问题
- 神奇的备忘录
- Python读取某个目录下的zip压缩包解压开后计算每个小文件的md5值,并将压缩包名字、里面小文件名字、以及对应的md5值写入csv文件
- Android 如何让EditText不自动获取焦点
- Codeforces Round #337 (Div. 2) D (矩形面积并
- java中String类为什么要设计成不可变的