2019蓝桥杯国赛B组第九题

题目描述:
有一条河,沿河的一侧生活着一个部落。这个一字型的部落有n个据点,从左至右依次编号1~n。
部落的人们有时会在某个据点建立建筑,每个建筑都有各自的价值。一开始,每个据点的都没有建筑,价值都是0。如果在已有建筑的据点建立新的建筑,那么新的建筑会代替旧的建筑(旧的建筑就此消失)。
有两种操作C和Q:
1、C x y,表示在据点x建立一个价值为y的建筑。
2、Q x y,询问在据点x~y之间(包括x,y)的建筑中,价值第八大的建筑的价值是多少。

输入描述:
第一行,两个正整数n和k,表示据点的数量和操作的数量。
接下的k行,每行一个操作。

输出描述:
对于所有的Q操作,输出相应的第八大建筑的价值。

输入样例:
10 14
C 1 5
C 2 4
C 3 7
C 4 6
C 5 5
C 6 1
C 7 8
Q 1 10
C 8 3
C 9 6
C 10 3
Q 1 9
C 6 10
Q 1 10

输出样例:
0
3
4
思路:唉,当时要是能想到这一点,也不会只拿个国二了。
很明显,区间操作,线段树是很容易想到的。但是这次线段树的每一个节点不是维护一个数了,而是8个数。因为8很小,所以还是可以承担的。每次pushup的时候,将最大的八个数更新给父节点。查询的时候返回一个数组就可以了。代码没有测试,不知道有没有问题,当个参考吧。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e5+100;
struct node{
	int l;
	int r;
	int a[9];
	int len;
}p[maxx<<2];
int n,m,x,y;

inline void pushup(int cur)
{
	int *c1=new int[9];
	int *c2=new int[9];
	int len1=p[cur<<1].len;
	int len2=p[cur<<1|1].len;
	sort(p[cur<<1].a,p[cur<<1].a+len1);
	sort(p[cur<<1|1].a,p[cur<<1|1].a+len2);
	c1=p[cur<<1].a;
	c2=p[cur<<1|1].a;
	int len=0;len1--,len2--;
	while(len<8&&(len1>=0&&len2>=0))
	{
		if(c1[len1]>c2[len2]) p[cur].a[len++]=c1[len1],len1--;
		else p[cur].a[len++]=c2[len2],len2--;
	}
	if(len1==-1) while(len<8&&len2>=0) p[cur].a[len++]=c2[len2--];
	else while(len<8&&len1>=0) p[cur].a[len++]=c1[len1--];
	while(len<8) p[cur].a[len++]=0;
	p[cur].len=len;
}
inline void build(int l,int r,int cur)
{
	p[cur].l=l;
	p[cur].r=r;
	p[cur].len=0;
	memset(p[cur].a,0,sizeof(p[cur].a));
	if(l==r) return ;
	int mid=l+r>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1);
}
inline void update(int pos,int v,int cur)
{
	int L=p[cur].l;
	int R=p[cur].r;
	if(L==R) 
	{
		p[cur].a[0]=v;
		p[cur].len=1;
		return ;
	}
	int mid=L+R>>1;
	if(pos<=mid) update(pos,v,cur<<1);
	else update(pos,v,cur<<1|1);
	pushup(cur);
}
inline int *query(int l,int r,int cur)
{
	int L=p[cur].l;
	int R=p[cur].r;
	if(l<=L&&R<=r) return p[cur].a;
	int mid=L+R>>1;
	if(r<=mid) return query(l,r,cur<<1);
	else if(l>mid) return query(l,r,cur<<1|1);
	else
	{
		int *c1=new int[9];
		c1=query(l,mid,cur<<1);
		int *c2=new int[9];
		c2=query(mid+1,r,cur<<1|1);
		sort(c1,c1+8);
		sort(c2,c2+8);
		int *c=new int[9];
		int len=0,len1=7,len2=7;
		while(len<8&&(len1>=0&&len2>=0))
		{
			if(c1[len1]>c2[len2]) c[len++]=c1[len1],len1--;
			else c[len++]=c2[len2],len2--;
		}
		if(len1==-1) while(len<8&&len2>=0) c[len++]=c2[len2--];
		else while(len<8&&len1>=0) c[len++]=c1[len1--];
		return c;
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	build(1,n,1);
	char s[2];
	while(m--)
	{
		scanf("%s%d%d",s,&x,&y);
		if(s[0]=='C') update(x,y,1);
		else 
		{
			int *c=new int[9];
			c=query(x,y,1);
			sort(c,c+8);
			printf("%d\n",c[0]);
		}
	}
	return 0;
}

努力加油a啊,(o)/~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值