POJ 2352 treap

当年经常遇到这种题,愣是没做出来,好像那时不会线段树,也不会平衡树。

凭借一身蛮力来搞,倒是和那群朋友搞得开开心心。

题意:

  y从小到大,若y相同,x从小到大,这样给出一些坐标,求每个点覆盖的点个数。

题解:

  每次只需计算小于等于当前x值得个数有多少即可。

  可用线段树或平衡树做,现在平衡树treap也是做了一定题了,比起线段树反而写起来更溜!

爽!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <ctime>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define INF 0x3f3f3f3f
#define MAXN 20005

using namespace std;

int cnt=1, rt=0;
int n,ans[MAXN],x,y;

struct Tree
{
    int key, pri, size, son[2];
    void set(int x, int y, int z)
    {
        key=x;
        pri=y;
        size=z;
        son[0]=son[1]=0;
    }
}T[MAXN];

void rotate(int p, int &x)
{
    int y=T[x].son[!p];
    T[x].size=T[x].size-T[y].size+T[T[y].son[p]].size;
    T[x].son[!p]=T[y].son[p];
    T[y].size=T[y].size-T[T[y].son[p]].size+T[x].size;
    T[y].son[p]=x;
    x=y;
}

void ins(int key, int &x)
{
    if(x == 0)
        T[x = cnt++].set(key, rand(), 1);
    else
    {
        T[x].size++;
        int p=key <= T[x].key;
        ins(key, T[x].son[!p]);
        if(T[x].pri > T[T[x].son[!p]].pri)
            rotate(p, x);
    }
}

int find(int key, int &x)
{
    if(x == 0)
        return 0;
    if(T[x].key <= key)
        return T[T[x].son[0]].size+1+find(key, T[x].son[1]);
    else
        return find(key, T[x].son[0]);
}

int main()
{
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d%d", &x, &y);
        ans[find(x, rt)]++;
        ins(x, rt);
    }
    for(int i=0; i<n; i++)
        printf("%d\n", ans[i]);
    return 0;
}

时间: 2025-01-01 21:15:51

POJ 2352 treap的相关文章

POJ - 2352 - Stars

题目链接:POJ - 2352 题目大意: 给你N个星星的坐标,问每个星星的左下角有几颗星星. 注意输入坐标y是按递增输入的. 题目分析: 算是树状数组的一个基础题目吧,有些题目也是以这道题为基础的. 直接运用数组数组即可,具体看代码. 不过注意由于x坐标有可能是0,所以要对所有的X坐标加一(不要忘了区间上界也要增大一个), 防止add()函数出现死循环超时. 给出代码: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cs

poj 2352 Stars 数星星 详解

题目: poj 2352 Stars 数星星 题意:已知n个星星的坐标.每个星星都有一个等级,数值等于坐标系内纵坐标和横坐标皆不大于它的星星的个数.星星的坐标按照纵坐标从小到大的顺序给出,纵坐标相同时则按照横坐标从小到大输出. (0 <= x, y <= 32000) 要求输出等级0到n-1之间各等级的星星个数. 分析: 这道题不难想到n平方的算法,即从纵坐标最小的开始搜,每次找它前面横坐标的值比它小的点的个数,两个for循环搞定,但是会超时. 所以需要用一些数据结构去优化,主要是优化找 横坐

POJ 2352

第一题树状数组 模板题 #include <cstdio> #include <iostream> using namespace std; int c[32002],lv[15002],n; int lowbit(int x){return x&(-x);} int sum(int b){ int sum=0; while(b>0){ sum+=c[b]; b-=lowbit(b); } return sum; } void add(int x){ while(x&

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

POJ 2352 Stars(线段树)

题目地址:POJ 2352 今天的周赛被虐了. . TAT..线段树太渣了..得好好补补了(尽管是从昨天才開始学的..不能算补...) 这题还是非常easy的..维护信息是每个横坐标的出现的次数. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h>

poj 2352 Stars (树状数组)

Stars Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37108   Accepted: 16173 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 st

POJ 2352 (stars)

[题意描述] 就是给定n个星星的x,y坐标,y坐标按照从小到大的顺序进行排列,x坐标随机排列.下面求对于每个星星而言,其它星星的x,y的坐标都小于等于该星星的数目,然后输出所有的情况. [思路分析] 我们这道题可以采用树状数组求解,将x+1作为树状数组的底标. [AC代码] #include<iostream> #include<bitset> #include<cstdio> #include<cstring> #include<algorithm&

Black Box(POJ 1442&#183;TREAP实现)

传送门:http://poj.org/problem?id=1442 Black Box Time Limit: 1000MS   Memory Limit: 10000K       Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empt

POJ 2352 star level

题目链接: http://poj.org/problem?id=2352 题目大意:对于每一颗星星来说,都有一个属于自己的level,这个值为其他星星x,y坐标均不大于本星星的个数.输入时按先y由小到大,再x由小到大排列,无相同位置的星星 仔细一想其实这道题目根本不需要用到y,我是反向来思考的,构建一个保存x坐标由0到maxn的线段树,因为最后一个星星肯定不可能x,y同时不大于其他星星,所 以从后面开始看,只计算比它x小或相等的星星的个数,用cnt[ans]++,来记录成为ans水平的个数,再删