POJ2352题解(树状数组)

POJ2352题解(树状数组)

2019-12-29

Powered by Gauss

1.题目传送门:POJ2352

2.题目大意:

这是一道非常经典的树状数组的模板题。

题目大意是说,给出N颗星星,每个星星都有一个二维坐标,要求出位于每颗星星左下方的星星的数量。

3.算法思路:

这道题被给出之后立刻想到暴力法,让我们来计算一下:

根据题目,N<=15000,暴力法需要双层循环,也就是150002=225,000,000,超出了一秒,所以不得不寻求更快更好的算法思想。

当我们需要求查询,求和的时候,应该想到使用树状数组。

同时,这道题的题目条件让我们具备了使用树状数组的条件:星按Y坐标的升序列出,Y坐标相等的星按X坐标的升序排列。

这样的话我们就可以免排序在输入的循环中直接计算:

for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        level[sum(++x)]++;
        add(x,1);
    }

其中level数组用来统计等级为0-N的每一级的星星的个数。

然后让我们来看一下树状数组的标配lowbit函数和sum函数:

int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=a[x];
        x-=lowbit(x);
    }
    return ans;
}
int lowbit(int x)
{
    return x&-x;
}

这样我们就方便了滞后的统计计算,下面给出完整AC代码:

#include<cstdio>
using namespace std;
const int maxn=32005;
int a[maxn],level[maxn],n,x,y;
int lowbit(int x)
{
    return x&-x;
}
void add(int x,int v)
{
    while(x<=maxn)
    {
        a[x]+=v;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=a[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        level[sum(++x)]++;
        add(x,1);
    }
    for(int i=0;i<=n-1;i++) printf("%d\n",level[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/Warframe-Gauss/p/12114956.html

时间: 2024-11-08 21:30:26

POJ2352题解(树状数组)的相关文章

POJ2352 Stars 树状数组

POJ2352 非常裸的树状数组的题. 注意数组下标不能从0开始 因为lowbit(0)==0 所以 所有横坐标统一加1 数组要开的够大 就酱 #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> using namespace std; const int maxn=15000,

luoguP2184 贪婪大陆 题解(树状数组)

P2184 贪婪大陆  题目 其实很容易理解就是询问一段区间内有多少段不同的区间 然后再仔细思索一下会发现: 1.只要一个区间的开头在一个节点i的左边,那么这个区间包含在区间1~i中. 2.只要一个区间的尾部在一个节点j的左边,那么这个区间肯定不属于j之后的所有区间 这时候就不难想到用两个树状数组维护: 第一个:维护节点i之前有多少个区间的开头 第二个:维护节点j之前有多少个区间的结尾 不难证明拿sum[i]-sum[j]得到的就是i~j中间地雷的个数(手动模拟一波就一清二楚了) #includ

poj--2352 Stars(树状数组)

Description Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. As

POJ2352(树状数组)

Stars Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33786   Accepted: 14741 题目链接:http://poj.org/problem?id=2352 Description Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesia

poj2352 starts 树状数组

有n个星星,按照y坐标的升序给出n个星星的坐标, 对于每一个星星,其level为在其左下方(包括正左,正下)的星星个数,输出n行,第i行代表等级为i个星星的星星的个数. 树状数组的插点问段 思路: a[i] 存储星星的x坐标, b[i] 表示0到i中x,y坐标小于i的个数,即i的等级 则对于每个b[i], 做一次扫描 ans[i] 表示等级为i的个数 则ans[b[i]]++; 明显,这样肯定tle. 所以要采用树状数组 . a[i] 表示目前的星星中x坐标为i的个数 c[i] 为a[i]的树状

[CTSC2017]最长上升自序列(伪题解)(树状数组+DP套DP+最小费用最大流+Johnson最短路+Yang_Tableau)

部分分做法很多,但每想出来一个也就多5-10分.正解还不会,下面是各种部分分做法: Subtask 1:k=1 LCS长度最长为1,也就是说不存在j>i和a[j]>a[i]同时成立.显然就是一个LDS,树状数组直接求即可. Subtask 2:k=2 最多两个,也就是可以由两个LCS拼起来,f[i][j]表示第一个LCS以i结尾,第二个以j结尾的方案数,转移显然. Subtask 3:k=2 树状数组优化DP,复杂度由$O(n^3)$降为$O(n^2 \log n)$ Subtask 4,5:

【bzoj2789】[Poi2012]Letters 树状数组求逆序对

题目描述 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. 输入 第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度. 第二行和第三行各一个长度为n的字符串,并且只包含大写英文字母. 输出 一个非负整数,表示最少的交换次数. 样例输入 3 ABC BCA 样例输出 2 题解 树状数组求逆序对 一个结论:将序列A通过交换相邻元素变换为序列B,需要的最小次数为A中

【树状数组】Bzoj1878[SDOI2009] HH的项链

Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变得越来越长.有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答...因为项链实在是太长了.于是,他只好求助睿智的你,来解 决这个问题. Input 第一行:一个整数N,表示项链的长度. 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的

【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

题目描述 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 样例输入 4 3 2 4 4 1 3 2 1 样例输出 3 题解 树状数组 WH说是CDQ分治直接把我整蒙了... 把所有数按照第一次出现位置从小到大排序,然后扫一遍.此时一定是满足$a_j>a_i$的. 那么只需要求出$(a_j,b_j)$中以前出现过的$b_i$的数目.使用树状数组维护即可. 时间复杂度$O(n\log n)$ #include &l