POJ 2352 splay

再撸一发splay。

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

using namespace std;

int cnt=1, rt=0;

struct Tree
{
    int key, size, fa, son[2];
    void set(int _key, int _size, int _fa)
    {
        key=_key;
        size=_size;
        fa=_fa;
        son[0]=son[1]=0;
    }
}T[MAXN];

inline void PushUp(int x)
{
    T[x].size=T[T[x].son[0]].size+T[T[x].son[1]].size+1;
}

inline void Rotate(int x, int p) //0左旋 1右旋
{
    int y=T[x].fa;
    T[y].son[!p]=T[x].son[p];
    T[T[x].son[p]].fa=y;
    T[x].fa=T[y].fa;
    if(T[x].fa)
        T[T[x].fa].son[T[T[x].fa].son[1] == y]=x;
    T[x].son[p]=y;
    T[y].fa=x;
    PushUp(y);
    PushUp(x);
}

void Splay(int x, int To) //将x节点插入到To的子节点中
{
    while(T[x].fa != To)
    {
        if(T[T[x].fa].fa == To)
            Rotate(x, T[T[x].fa].son[0] == x);
        else
        {
            int y=T[x].fa, z=T[y].fa;
            int p=(T[z].son[0] == y);
            if(T[y].son[p] == x)
                Rotate(x, !p), Rotate(x, p);
            else
                Rotate(y, p), Rotate(x, p);
        }
    }
    if(To == 0) rt=x;
}

void Insert(int key)
{
    if(rt == 0)
        T[rt = cnt++].set(key, 1, 0);
    else
    {
        int x=rt, y=0;
        while(x)
        {
            y=x;
            x=T[x].son[key > T[x].key];
        }
        T[x = cnt++].set(key, 1, y);
        T[y].son[key > T[y].key]=x;
        Splay(x, 0);
    }
}

int GetRank(int key)
{
    if(!rt) return 0;
    int x=rt, ret=0, y;
    while(x)
    {
        y=x;
        if(T[x].key <= key)
        {
            ret+=T[T[x].son[0]].size+1;
            x=T[x].son[1];
        }
        else
            x=T[x].son[0];
    }
    Splay(y, 0);
    return ret;
}

int n,m,a[MAXN],u[MAXN],x,y,ans[MAXN];

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

听说splay更常用于区间操作,待我再去挖掘。

时间: 2024-08-05 19:04:32

POJ 2352 splay的相关文章

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 3468 Splay 树

大二上的时候,写过一个AVL的操作演示,今天一看Splay,发现和AVL其实一样,加上线段树的基础,懒惰标记什么都知道,学起来轻松许多哦 我参考的模板来自这里  http://blog.csdn.net/u013480600/article/list/2 里面有大量的ch[r][0] ch[r][1]等 我建议用宏定义取代,写的时候方括号少打了很多,等做的题多得时候,我再把自己使用的模板发来 #include <cstdio> #include <cstring> #include

POJ 2352 (stars)

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

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水平的个数,再删