【洛谷】1533 可怜的狗狗 平衡树

110 篇文章 0 订阅
10 篇文章 0 订阅

题目传送门

这题嘛,一拿到手,我第一反应是线段树套平衡树……然后就被ZH大佬D了:“这题不是排个序加平衡树就好了吗?”

QAQ,大佬就是大佬,一针见血的解决了题目。然后JYZ来问:“这一定是一道很难的题目吧?”“不会啊,一道傻逼模板题罢了。”ZH大佬淡淡的说。

(JYZ大佬只是在装弱罢了,他太强了,不过一个大佬%比他弱的人是要降RP的)


这题的题目中明确指出:每个区间不互相包含。

因此我们可以把所有的询问排个序,然后维护一棵平衡树,平衡树内的所有节点为当前询问区间内的所有狗狗的漂亮值。

在区间转换时,只需要删去前面多余的节点,增加后面需要的节点,维护平衡树就行了。

附上AC代码:

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstdlib>
#define N 300010
using namespace std;

struct note{
	int x,y,w,wz;
	bool operator < (const note lyf) const {
		if (x==lyf.x) return y<lyf.y;
		return x<lyf.x;
	}
}a[50010];
struct tree{
	int w,g,size,rnd;
}t[N];
int n,m,w[N],size,l,r,rt,son[N][2],ans[50010];

inline char nc(){
	static char ch[100010],*p1=ch,*p2=ch;
	return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}

inline void read(int &a){
	static char c=nc();int f=1;
	for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
	for (a=0;isdigit(c);a=a*10+c-'0',c=nc());
	a*=f;return;
}

inline void turn(int &k,int x){
	int p=son[k][x];
	son[k][x]=son[p][x^1];
	son[p][x^1]=k;
	t[k].size=t[son[k][0]].size+t[son[k][1]].size+t[k].g;
	t[p].size=t[son[p][0]].size+t[son[p][1]].size+t[p].g;
	k=p;return;
}

inline void ist(int &k,int x){
	if (!k){
		k=++size,t[k].w=x,t[k].g=t[k].size=1,t[k].rnd=rand();
		return;
	}
	++t[k].size;
	if (t[k].w==x) ++t[k].g;
	else if (t[k].w<x){
		ist(son[k][1],x);
		if (t[son[k][1]].rnd<t[k].rnd) turn(k,1);
	}
	else{
		ist(son[k][0],x);
		if (t[son[k][0]].rnd<t[k].rnd) turn(k,0);
	}
	return;
}

inline void del(int &k,int x){
	if (!k) return;
	if (t[k].w==x){
		if (t[k].g>1){
			--t[k].g,--t[k].size;
			return;
		}
		if (son[k][0]*son[k][1]==0) k=son[k][0]+son[k][1];
			else if (t[son[k][0]].rnd<t[son[k][1]].rnd) turn(k,0),del(k,x);
				else turn(k,1),del(k,x);
	}
	else{
		--t[k].size;
		if (t[k].w<x) del(son[k][1],x);
			else del(son[k][0],x);
	}
	return;
}

inline int query(int k,int x){
	if (!k||x>t[k].size||x<=0) return 0;
	if (t[son[k][0]].size+t[k].g<x) return query(son[k][1],x-t[son[k][0]].size-t[k].g);
		else if (t[son[k][0]].size+1>x) return query(son[k][0],x);
			else return t[k].w;
}

int main(void){
	read(n),read(m);
	for (int i=1; i<=n; ++i) read(w[i]);
	for (int i=1; i<=m; ++i) read(a[i].x),read(a[i].y),read(a[i].w),a[i].wz=i;
	sort(a+1,a+1+m),l=1,r=0;
	for (int i=1; i<=m; ++i){
		while (r<a[i].y) ist(rt,w[++r]);
		while (l<a[i].x) del(rt,w[l++]);
		ans[a[i].wz]=query(rt,a[i].w);
	}
	for (int i=1; i<=m; ++i) printf("%d\n",ans[i]);
	return 0;
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值