题目链接: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;
}