树状数组---逆序类题目
2016-08-10 20:38
281 查看
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;
}
相关文章推荐
- HDOJ题目1541 Stars(树状数组单点更新)
- 线段树和树状数组题目总结(未完)
- HDOJ 题目2838 Cow Sorting(树状数组逆序对)
- 南阳理工oj 题目116 士兵杀敌(二)树状数组
- 树状数组题目总结三( 上)( HOJ 2275 Number sequence )
- 线段树和树状数组题目总结(未完)
- POJ 题目2299 Ultra-QuickSort(树状数组求逆序对)
- HDOJ 题目1166敌兵布阵(树状数组)
- POJ 题目3928 Ping pong(树状数组)
- HDOJ 题目2227 Find the nondecreasing subsequences(树状数组,离散化,DP)
- ( poj 2352,poj 3067, poj2481)树状数组题目总结(二)
- poi 1990 MooFest(树状数组题目,转换成两个树状数组来做)较难的题目****
- POJ 题目2182 Lost Cows(树状数组+二分)
- poj 3067 Japan(树状数组,注意题目向树状数组的转换)
- hdu 二维树状数组 简单题目 靠。。。。。扯蛋的悲哀,如果上天给我一种干掉你的愿望,我宁愿放弃——努力的结晶
- HDOJ 题目1166 敌兵布阵(树状数组单点跟新)
- 树状数组题目总结(一)
- 南阳理工acm 题目116 士兵杀敌(二)树状数组
- hrbust 2046 哈理工oj 2046 最后的题目八个字【二维树状数组】
- 树状数组学习以及题目总结