poj 2352 treap

来源:互联网 发布:苍穹测绘软件视频教程 编辑:程序博客网 时间:2024/06/06 05:08

题意:先按Y的升序然后再按X的升序给出坐标,求出每个坐标左下方有多少个点,最后输出有从0到n-1个点的坐标有多少个。

分析:本题可以看成是 树状数组的入门题,但是用treap同样也可以解决。由于坐标是按照y递增的顺序输入。所以不需要记录、处理y坐标,对x坐标维护一个treap,对每个节点维护一个总节点数sum。 虽然没有完全相同的两个点,但是x坐标可以相同,所以储存一个当前节点的个数val,最后计算的时候这是要考略的,由于忽略这个WA了三次。

简单的treap,每次插入一个x,然后查询小于等于它的节点的个数就行了。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;struct node{    int r,v,sum,val;    node* ch[2];    node (int v):v(v){ch[0] = ch[1] = NULL; r = rand(); sum = 1; val = 1;}    bool operator <(const node &a) const    {        return r <a.r;    }    int cmp(int x)    {        if(v == x) return -1;        return x < v ? 0 : 1;    }};node *root;void pushup(node* &o){        o->sum = o->val;    if(o->ch[0] != NULL) o->sum += o->ch[0]->sum;    if(o->ch[1] != NULL) o->sum += o->ch[1]->sum;}void rotate(node* &o, int d){    node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d];k ->ch[d] = o;    pushup(o);    pushup(k);    if(o == root) root = k;    o = k;}void insert(node* &o, int x){    if(o == NULL) o = new node(x);    else    {        int d = o->cmp(x);        if(d == -1)        {            o->val ++;            o->sum ++;        }        else        {         insert(o->ch[d],x);         pushup(o);         if(o->ch[d]->r > o->r) rotate(o,d^1);        }    }}int find(node* &o, int x){    //cout << o->v <<"    " << x << endl;    int ans = 0;    int d = o->cmp(x);    if(d == -1)    {        ans += o->val - 1;        if(o->ch[0] != NULL) ans += o->ch[0]->sum;        return ans;    }    else    {        if(d == 1) ans += o->val;        if(d == 1 && o->ch[0] != NULL) ans += o->ch[0]->sum;        return ans += find(o->ch[d],x);    }}int ans[15000+ 5];int main(){      int n;      while(~scanf("%d",&n))      {          root = NULL;          memset(ans,0,sizeof(ans));          for(int i = 1; i <= n; i++)          {              int x,y; scanf("%d %d",&x,&y);              insert(root,x);               int pos = find(root,x);               //cout << pos << endl;               ans[pos] ++;          }          for(int i = 0; i < n; i ++)          {              printf("%d\n",ans[i]);          }      }}


原创粉丝点击