您的位置:首页 > 其它

数状数组

2010-11-14 00:30 176 查看
  树状数组不用多讲了,网上有关于这方面的内容很多,找找都是一大片,而且也不是很难,去学一下就可以很快领悟,至于怎么用,这就需要大量的做题了!

先提个注意点,由于Lowbit(0) = 0,这会导致x递增的那条路径发生死循环,所有当树状数组中可能出现0时,我们都全部加一,这样可以避免0带来的麻烦~~

简单:

POJ 2299 Ultra-QuickSort
http://acm.pku.edu.cn/JudgeOnline/problem?id=2299
求逆序数,可以用经典的归并排序做,也是基本的树状数组题目。

因为a[i]比较大,但只有最多500000个,所以要离散化。

逆序数就是求前面的数比后面的数大的次数。从后往前看就是求后面比前小的数的个数。用树状数组!c[i]表示比i的值小的个数。

代码

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200005
struct node
{
int x;
int y;
int LeftPoint; //正左边的点数
int RightPoint; //正右边的点数
int UpPoint; //正上方的点数
int DownPoint; //正下方的点数
int LargeY; //比该点Y大的数的数目
}p[maxn];
int C[maxn];
int BL,TL,TR,BR;
/*对第j个点的四块内的点数
BL = Getsum(p[j].y) - p[j].LeftPoint - p[j].DownPoint;
TL = j - p[j].LeftPoint - p[j].DownPoint - BL;
TR = p[j].LargeY - TL - p[j].UpPoint;
BR = n - j - 1 - TR - p[j].RightPoint - p[j].UpPoint;
*/
struct node1
{
int Stan;
int Ollie;
}V[maxn];
bool cmp(node a,node b)
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
bool cmp2(node a,node b)
{
if(a.y == b.y)
return a.x < b.x;
return a.y < b.y;
}
bool cmp3(node1 a,node1 b)
{
if(a.Stan == b.Stan)
return a.Ollie < b.Ollie;
return a.Stan > b.Stan;
}
//bool cmp1(node a,node b){return a.x < b.x;}

int lowb(int t)
{
return t&(-t);
}
void Updata(int i)
{
while(i<maxn)
{
C[i] += 1;
i += lowb(i);
}
}
int Getsum(int i)
{
int s = 0;
while(i>0)
{
s += C[i];
i -= lowb(i);
}
return s;
}
int main()
{
int i,j,k;
int n,num;
while(scanf("%d",&n)!=EOF && n!=0)
{
memset(C,0,sizeof(C));
for(i=0;i<n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
sort(p,p+n,cmp); //X轴离散化
for(num=1,i=0;i<n;num++)
{
for(j=i+1;j<n;j++)
{
if(p[i].x != p[j].x)
break;
}
for(k=i;k<j;k++)
{
p[k].UpPoint = j-1-k;
p[k].DownPoint = k - i;
p[k].x = num;
}
i = j;
}
sort(p,p+n,cmp2);//Y轴离散化
for(num=1,i=0;i<n;num++)
{
for(j=i+1;j<n;j++)
{
if(p[i].y != p[j].y)
break;
}
for(k=i;k<j;k++)
{
p[k].LeftPoint = k - i;
p[k].RightPoint = j-1-k;
p[k].y = num;
p[k].LargeY = n - j;
}
i = j;
}
sort(p,p+n,cmp);
for(num=0,i=0;i<n;num++)
{
int Stan_num = 0x7fffffff;
int Ollie_num = 0;
for(j=i;j<n;j++)
{
if(p[j].x != p[i].x)
break;
BL = Getsum(p[j].y) - p[j].LeftPoint - p[j].DownPoint;
TL = j - p[j].LeftPoint - p[j].DownPoint - BL;
TR = p[j].LargeY - TL - p[j].UpPoint;
BR = n - j - 1 - TR - p[j].RightPoint - p[j].UpPoint;

if(TL + BR > Ollie_num)
{
Stan_num = BL + TR;
Ollie_num = TL + BR;
}
else if(TL + BR == Ollie_num)
{
if(BL + TR <= Stan_num)
{
Stan_num = BL + TR;
}
}
Updata(p[j].y);
}
V[num].Ollie = Ollie_num;
V[num].Stan = Stan_num;
i = j;
}
sort(V,V+num,cmp3);
printf("Stan: %d; Ollie:",V[0].Stan);
for(i=0;i<num;i++)
{
if(V[i].Stan != V[0].Stan)
break;
if(V[i].Ollie == V[i-1].Ollie && i != 0)
continue;
printf(" %d",V[i].Ollie);
}
printf(";\n");
}
//system("pause");
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: