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

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\n",cnt[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xwww666666/p/11650111.html
今日推荐