POJ 2352 Stars(treap练习)

题目链接:http://poj.org/problem?id=2352

题意:给出平面上一些点,每个点的level值为其左下角的点的个数(包括正下和左侧)。输出level值在[0,n-1] 的点各有多少个?

思路:由于给出的点是按照y升序然后x升序,所以将x插入treap,每次统计左子树的节点个数。





struct node

{

    int L,R,key,pri,cntL,cntR;

};



class treap

{

public:

    node p[N];

    int size,root;



    void init()

    {

        srand(time(0));

        size=root=-1;

    }



    void rotL(int &x)

    {

        int y=p[x].R;

        p[x].R=p[y].L;

        p[x].cntR=p[y].cntL;

        p[y].L=x;

        p[y].cntL=p[x].cntL+p[x].cntR+1;

        x=y;

    }



    void rotR(int &x)

    {

        int y=p[x].L;

        p[x].L=p[y].R;

        p[x].cntL=p[y].cntR;

        p[y].R=x;

        p[y].cntR=p[x].cntL+p[x].cntR+1;

        x=y;

    }



    void insert(int &k,int key)

    {

        if(k==-1)

        {

            k=++size;

            p[k].L=p[k].R=-1;

            p[k].cntL=p[k].cntR=0;

            p[k].key=key;

            p[k].pri=rand();

        }

        else if(key<p[k].key)

        {

            p[k].cntL++;

            insert(p[k].L,key);

            if(p[p[k].L].pri>p[k].pri) rotR(k);

        }

        else

        {

            p[k].cntR++;

            insert(p[k].R,key);

            if(p[p[k].R].pri>p[k].pri) rotL(k);

        }

    }





    int find(int k,int key)

    {

        if(k==-1) return 0;

        if(key<p[k].key) return find(p[k].L,key);

        return p[k].cntL+1+find(p[k].R,key);

    }

};



struct point

{

    int x,y;



    void get()

    {

        RD(x,y);

    }

};





point p[N];

treap a;

int n,ans[N];



int main()

{

    Rush(n)

    {

        a.init(); clr(ans,0);

        int i;

        FOR0(i,n) p[i].get();

        FOR0(i,n)

        {

            a.insert(a.root,p[i].x);

            ans[a.find(a.root,p[i].x)-1]++;

        }

        FOR0(i,n) PR(ans[i]);

    }

    return 0;

}

  

你可能感兴趣的:(tar)