洛谷 2343 宝石管理系统 题解

博客观赏效果更佳

题意简述

给定一个序列,维护两种操作,加入一个数,求第 k k k大的数。

思路

很明显这个题目珂以用平衡树做。但是,有一个引人深思的问题:你会写平衡树么?

但是,

颤抖吧,我可是会写STL的男人!

我可是有STL的男人,会怕你这sb题?!

所以我们考虑用 v e c t o r vector vector做这个问题。插入的时候,我们只要 l o w e r b o u n d lower_bound lowerbound一下找到一个正确的位置,然后插入进去即珂。这样保证了每次插入完之后的序列都是升序的。然后我们只要找到 v . e n d ( ) − k v.end()-k v.end()k的位置,就是第 k k k大了(由于我们是从小到大排,所以要找第 k k k大要从后面找)。

那么问题来了,如何插入?

insert()函数。等等。。。它不是 O ( n ) O(n) O(n)的么?但是只要你真诚的向珂朵莉祈祷,珂朵莉就会放你过的。

你们当刚强壮胆,不要害怕,也不要畏惧他们,写他娘的STL,因为珂朵莉你的神和你同去。他必不卡掉你,也不会让你WA。

——珂学圣经

代码:

#include<bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
	#define F(i,l,r) for(int i=l;i<=r;++i)
	#define D(i,r,l) for(int i=r;i>=l;--i)
	#define Fs(i,l,r,c) for(int i=l;i<=r;c)
	#define Ds(i,r,l,c) for(int i=r;i>=l;c)
	#define Tra(i,u) for(int i=G.Start(u);~i;i=G.Next(i))
	#define MEM(x,a) memset(x,a,sizeof(x))
	#define FK(x) MEM(x,0)
	class Balance_Tree
	{
		public:
			vector<int> v; 
			void Init()
			{
				v.clear();
			}

			int Rank(int i)
			{
				return *(v.begin()+i);
			}
			int rRank(int i)
			{
				return *(v.end()-i);
			}
			
			#define LB lower_bound(v.begin(),v.end(),x)
			#define RB upper_bound(v.begin(),v.end(),x)
			void Insert(int x)
			{
				v.insert(LB,x);
			}
	}T;
	
	void R1(int &x)
	{
	    x=0;char c=getchar();int f=1;
	    while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
	    while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	    x=(f==1)?x:-x;
	}
	void Input_Soviet()
	{
		int n,q;
		R1(n),R1(q);
		T.Init();
		F(i,1,n)
		{
			int x;R1(x);
			T.Insert(x);
		}
		F(i,1,q)
		{
			int c;R1(c);
			int x;R1(x);
			if (c==1)
			{
				printf("%d\n",T.rRank(x));
			}
			else if (c==2)
			{
				T.Insert(x);
			}
		}
	}

	void IsMyWife()
	{
		Input_Soviet();
	}
}
int main()
{
	Flandre_Scarlet::IsMyWife();
	getchar();getchar();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值