Splay

小鱼比可爱

题目描述

人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。

输入格式

第一行输入一个整数 \(n\),表示鱼的数目。

第二行内输入 \(n\) 个整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度。

输出格式

行内输出 \(n\) 个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。

输入输出样例

样例输入1

6
4 3 0 5 1 2

样例输出1

0 0 0 3 1 2

说明/提示

对于 \(100\%\) 的数据,\(n\leq 100\)

#include <bits/stdc++.h>

using namespace std;

const int N = 410, INF = 0x3f3f3f3f;
int n,res;
int a[N];
int root , idx	, tag;

struct Node 
{
	int s[2],v,p;
	int flag,size,cnt;
	
	void init(int _v,int _p)
	{
		v = _v, p = _p;		
		size = 1,cnt = 1;
	}
}tr[N];

void pushup(int u)
{
	tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + tr[u].cnt;
}

void rotate(int x)
{
	int y = tr[x].p,z = tr[y].p;
	int k = tr[y].s[1] == x;
	tr[z].s[tr[z].s[1] == y] = x,	tr[x].p = z;
	tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k^ 1]].p = y;
	tr[x].s[k ^ 1] = y,tr[y].p = x;
	pushup(y),	pushup(x);
}

void splay(int x, int k)
{
	
	while(tr[x].p != k)
	{
		int y = tr[x].p,	z = tr[y].p;
		if(z != k)
			if(tr[z].s[1] == y ^ tr[y].s[1] == x)	rotate(x);
			else rotate(y);
		rotate(x);
	}
	if(!k) root = x;
}

void insert(int x)
{
	int u =root, p = 0;
	while(u)
	{
		if(tr[u].v==x)
		{
			tr[u].cnt ++;
			pushup(u);
			splay(u,0);
			goto next_;
		}
		p = u,	u = tr[u].s[ x > tr[u].v ];		
	}
	u = ++ idx;
	if(p)	tr[p].s[ x > tr[p].v ] = u;
	tr[u].init(x,p);
	splay(u,0);
	next_:;
	
}

int get(int x)
{
	int u =root, res;
	while(u)
	{
		if(tr[u].v >= x)	res = u,u = tr[u].s[0];
		else u = tr[u].s[1];
	}
	return res;
	
}

int get_rank(int p, int x)
{
	if(p ==0) return -1;
	else if( x == tr[p].v)
	{
		tag = p;
		return tr[tr[p].s[0]].size + 1;
	}
	else if ( x < tr[p].v) return get_rank(tr[p].s[0],x);
	else return get_rank(tr[p].s[1],x) + tr[tr[p].s[0]].size + tr[p].cnt ;
	
}

int get_k(int k)
{
	int u = root;
	while(u)
	{
		if(tr[tr[u].s[0]].size >= k )	u = tr[u].s[0];
		else if(tr[tr[u].s[0]].size + 1 == k) return tr[u].v;//return u;
		else k -= tr[tr[u].s[0]].size + 1,	u = tr[u].s[1];
	}
	return -1;
}


int main()
{
	cin >> n;
	insert(-INF),insert(INF);
	//cout << "L : " << L << ' ' << "R : " << R << endl;
	for(int i= 1 ; i <= n ; i++)	
	{
		int x; cin >>	x; 
		insert(x);
		//splay(R,0);	R = get(x);	splay(L,R);
		cout << get_rank(root,x) - 2 << ' ' ;
		splay(tag,0);
		//cout << tr[tr[x].s[0]].size << endl;
		//cout << get(x) << ' ' << get_k(2) << ' ' << endl;
	}
	
}
posted @ 2022-02-26 17:13  HarySeldon  阅读(132)  评论(0)    收藏  举报