数星星(单点更新,求前缀和)

Posted nonames

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数星星(单点更新,求前缀和)相关的知识,希望对你有一定的参考价值。

http://acm.hdu.edu.cn/showproblem.php?pid=1541

题意:二维平面坐标上,给出n个星星的坐标,规定每个星星的左下方向的星星数量为该星星的等级。

统计1-n-1等级的数量。

解法:因为给出顺序的特殊性,可以用树状数组统计各星星的等级。

注意两点:1、该题为多组输入(该题没讲。。没有就T)

2、坐标范围从0开始,而树状数组一般从一开始,所以将坐标都加一。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int x[15009] , y[15009];
int xm  ;
int ans[15009];
int c[32009];
int lowerbit(int x)
{
    return x&(-x) ;
}

void add(int x , int val)
{
    for(int i = x ; i <= xm ; i += lowerbit(i))
    {
        c[i] += val ;
    }
}

int getsum(int x)
{
    int ans = 0 ;
    for(int i = x ; i >= 1 ; i -= lowerbit(i))
    {
        ans += c[i];
    }
    return ans ;
}

int main()
{
    int n ;
    while(~scanf("%d" , &n))
    {
        memset(c , 0 , sizeof(c));
        memset(ans , 0 , sizeof(ans));
        for(int i = 0 ; i < n ; i++)
        {
            scanf("%d%d" , &x[i] , &y[i]);
            x[i]++;
            xm = max(x[i] , xm) ;
        }
        int sum = 0 ;
        for(int i = 0 ; i < n ; i++)
        {
            sum = getsum(x[i]);
            add(x[i] , 1);
            ans[sum]++ ;
        }
        for(int i = 0 ; i < n ; i++)
        {
            cout << ans[i] << endl ;
        }
    }

    return 0 ;
}

 

以上是关于数星星(单点更新,求前缀和)的主要内容,如果未能解决你的问题,请参考以下文章

树状数组区间更新

AcWing 1265. 数星星(二维偏序问题+树状数组)

天上的星星 (前缀和)

天上的星星(二维前缀和)

更新区间,求单点—— luogu 3368

树状数组区间修改,区间更新:差分数组的运用