题目大意:
给出n个y坐标递减的星星坐标,每个星星都有一个一个等级是这颗星星下边和右边的星星总数(水平垂直也算),求每个星星的等级。
题目思路: 用2叉树统计星星个数,treap优化,下边不用算:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
struct node{
int s[3];
int sum,x,o;
}t[10000010];
int a[10000010];
int o=1,r;
int lily(int x,int &r){//运算
if(r==0)
return 0;
if(t[r].x>x)
return lily(x,t[r].s[0]);//递归
return t[t[r].s[0]].sum+1+lily(x,t[r].s[1]);
}
void lily3(int w,int &r){//旋转
int k=t[r].s[w];
t[r].sum=t[r].sum-t[k].sum+t[t[k].s[!w]].sum;
t[r].s[w]=t[k].s[!w];
t[k].sum=t[k].sum-t[t[k].s[!w]].sum+t[r].sum;
t[k].s[!w]=r;
r=k;
}
void lily2(int x,int &r){
if(r==0){//当是第一个时插入
r=o++;
t[r].s[1]=t[r].s[0]=0;
t[r].o=rand();//随机化
t[r].x=x;
t[r].sum=1;
return;
}
t[r].sum++;//累加
if(x<=t[r].x)//判断
lily2(x,t[r].s[0]);
else lily2(x,t[r].s[1]);
if(x<=t[r].x)
if(t[r].o<t[t[r].s[0]].o)//不符合旋转
lily3(0,r);
if(x>t[r].x)
if(t[r].o<t[t[r].s[1]].o)不符合旋转
lily3(1,r);
}
int main(){
int i,j,k,m,n,x,y;
while(scanf("%d",&n)!=EOF){
o=1;
r=0;
memset(a,0,sizeof(a));
for(i=1;i<=n;i++){
scanf("%d%d",&x,&y);
int d=lily(x,r);
a[d]++;//统计
lily2(x,r);
}
for(i=0;i<n;i++)
printf("%d\n",a[i]);//输出
}
return 0;
}