刷题数据结构树状数组线段树

Posted xwww666666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题数据结构树状数组线段树相关的知识,希望对你有一定的参考价值。

1>数星星

(复制自他人博客)

由于题目中给的数据是按y轴排序,我们只需构建x轴的树状数组,也就是说我们只需统计星星i之前一共有多少个x坐标小于或等于Xi的星星,这个数值也就是星星i的等级

又因为树状数组无法处理下标为0的元素(会死循环),所以要把每个x坐标+1

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int max(int a,int b)
{ return a>b ?a :b; }
int n,mx;
const int N=15003,M=33000;
struct node
{
    int x,y,xh;
    bool operator < (const node & o) const
    { return x!=o.x ?x<o.x :y<o.y; }
}d[N];
int ans[N],cnt[N];

int tr[M];
int lowbit(int x)
{ return x&(-x); }
void add(int pos)
{
    while(pos<=mx) 
        tr[pos]++,pos+=lowbit(pos);
}
int query(int pos)
{
    int ans=0;
    while(pos>0)
        ans+=tr[pos],pos-=lowbit(pos);
    return ans;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&d[i].x ,&d[i].y ),d[i].xh =i,
        d[i].x ++,d[i].y ++,mx=max(mx,d[i].y );
    sort(d+1,d+n+1);
    
    for(int i=1;i<=n;i++)
    {
        ans[d[i].xh ]=query(d[i].y );
        add(d[i].y );
        cnt[ans[d[i].xh ]]++;
    }
    
    for(int i=0;i<n;i++) printf("%d
",cnt[i]);
    return 0;
}

 

以上是关于刷题数据结构树状数组线段树的主要内容,如果未能解决你的问题,请参考以下文章

树状数组和线段树的那些事

线段树&树状数组

树状数组

树状数组与线段树

树状数组

菜鸡2014X的数据结构学习小结:线段树与树状数组