《算法竞赛进阶指南》 0x45 ~ 0x48 代码 + 杂谈

点分治

///淀粉质
链接 : https://blog.csdn.net/qq_40831340/article/details/90234372

平衡树

theap 模板

// treap模板题
// 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
//插入x数
//删除x数(若有多个相同的数,因只删除一个)
//查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
//查询排名为x的数
//求x的前驱(前驱定义为小于x,且最大的数)
//求x的后继(后继定义为大于x,且最小的数)
const int maxn = 100000+5;
const int INF = 0x3f3f3f3f;
int siz[maxn];
int s[maxn][3];
int w[maxn],pos[maxn];
int tot;

void up(int i) {siz[i]=siz[s[i][0]]+siz[s[i][1]]+1;}

void spin(int &i,int p) {
	int t=s[i][p];
	s[i][p]=s[t][!p],s[t][!p]=i,up(i),up(t),i=t;
}

void ins(int x,int &i) {
	if(!i) {
		i=++tot,siz[i]=1,w[i]=x,pos[i]=rand();
		return;
	}
	siz[i]++;
	if(x<=w[i]) {
		ins(x,s[i][0]);
		if(pos[s[i][0]]<pos[i])spin(i,0);
	} else {
		ins(x,s[i][1]);
		if(pos[s[i][1]]<pos[i])spin(i,1);
	}
}

void del(int x,int &i) {
	if(w[i]==x) {
		if(s[i][0]*s[i][1]==0) {
			i=s[i][0]+s[i][1];
			return;
		}
		if(pos[s[i][0]]>pos[s[i][1]]) {
			spin(i,1);
			del(x,s[i][0]);
		} else {
			spin(i,0);
			del(x,s[i][1]);
		}
	} else if(w[i]>x)del(x,s[i][0]);
	else del(x,s[i][1]);
	up(i);
}

int find(int x,int i) {
	if(!i)return 1;
	if(w[i]>=x)return find(x,s[i][0]);
	return find(x,s[i][1])+siz[s[i][0]]+1;
}

int ask(int x,int i) {
	if(siz[s[i][0]]==x-1)return w[i];
	if(siz[s[i][0]]>=x)return ask(x,s[i][0]);
	return ask(x-siz[s[i][0]]-1,s[i][1]);
}

int pre(int x,int i) {
	if(!i)return -INF;
	if(w[i]<x)return max(w[i],pre(x,s[i][1]));
	else return pre(x,s[i][0]);
}
int nxt(int x,int i) {
	if(!i)return INF;
	if(w[i]>x)return min(w[i],nxt(x,s[i][0]));
	else return nxt(x,s[i][1]);
}

signed main() {
	cin>>n;
	int root=0;
	while(n--) {
		int cmd;
		cin>>cmd;
		if(cmd==1) cin>>m,ins(m,root);
		if(cmd==2) cin>>m,del(m,root);
		if(cmd==3) cin>>m,cout<<find(m,root)<<endl;
		if(cmd==4) cin>>m,cout<<ask(m,root)<<endl;
		if(cmd==5) cin>>m,cout<<pre(m,root)<<endl;
		cmd==6;
		cin>>m,cout<<nxt(m,root)<<endl;
	}
	return 0;
}

可持续化
链接 https://blog.csdn.net/qq_40831340/article/details/90733094

#include <iostream>
#include <cstdio>
using namespace std;
const signed maxn =  600000+10;
signed trie[maxn * 24][2], latest[maxn * 24];
signed s[maxn], root[maxn], n, m, tot;
inline void ins(int i, int k, int p, int q){
	if(k < 0) {
		latest[q] = i;
		return ;
	}
	int c = s[i] >> k & 1;
	if(p) trie[q][c ^ 1] = trie[p][c ^ 1];
	trie[q][c] = ++tot;
	ins(i, k-1, trie[p][c], trie[q][c]);
	latest[q] = max (latest[trie[q][0]], latest[trie[q][1]]); 
}
signed ask(int now, int val, int k, int limit) {
	if(k < 0) return s[latest[now]] ^ val;
	int c = val >> k & 1;
	if(latest[trie[now][c ^ 1]] >= limit)
		return ask(trie[now][c ^ 1], val, k - 1, limit);
	else 
		return ask(trie[now][c], val, k - 1, limit);
} 
signed main(){
	scanf("%d %d",&n,&m);
	latest[0] = -1;
	root[0] = ++tot;
	ins(0, 23, 0, root[0]);
	int x;
	for(int i = 1; i <= n ; i ++ ) {
		scanf("%d",&x);
		s[i] = x ^ s[i - 1];
		root[i] = ++ tot;
		ins(i, 23, root[i - 1], root[i]);
	}
	for(int i = 1; i <= m; i ++) {
		int l, r;
		char cmd[2];
		scanf("%s",cmd);
		if(cmd[0] == 'A') {
			scanf("%d",&x);
			root[++n] = ++ tot;
			s[n] = s[n - 1] ^ x;
			ins(n, 23, root[n - 1], root[n]);
		}else{
			scanf("%d %d %d",&l, &r,&x);
			cout << ask(root[r - 1], x ^ s[n], 23, l - 1) << endl;
		}
	}
	return 0;
}
全部评论

相关推荐

2025-12-27 18:11
已编辑
门头沟学院 前端工程师
28双非鼠鼠第一份实习,感谢金山,感谢面试官张先生的赏识,也感谢自己很开心很开心(有没有待过的前辈,求摸鱼技巧bushi)timeline12.15&nbsp;投递12.16&nbsp;约面12.18&nbsp;一面&nbsp;半个小时后约二面12.19&nbsp;二面,口头oc12.24&nbsp;发offer一面1.&nbsp;开发页面中使用的布局方式2.&nbsp;flex:&nbsp;1&nbsp;是什么的缩写3.&nbsp;水平居中的方法4.&nbsp;tailwindcss&nbsp;的优势5.&nbsp;js&nbsp;的闭包6.&nbsp;打印结果的题,解释为什么(var&nbsp;定义&nbsp;i&nbsp;,setTimeout&nbsp;执行打印),使用&nbsp;let&nbsp;的打印结果7.&nbsp;箭头函数和普通函数的区别8.&nbsp;promise&nbsp;构造函数是同步还是异步9.&nbsp;内存泄漏的情况10.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别11.&nbsp;react&nbsp;的&nbsp;key&nbsp;作用12.&nbsp;常用的钩子函数13.&nbsp;怎么避免不必要的渲染14.&nbsp;useeffect&nbsp;的使用场景15.&nbsp;react&nbsp;和&nbsp;vue&nbsp;怎么选择16.&nbsp;vue&nbsp;的&nbsp;data&nbsp;为什么用函数17.&nbsp;tcp&nbsp;为什么需要三次握手和四次挥手18.&nbsp;vite&nbsp;为什么比较快19.&nbsp;解释防抖节流和手写防抖函数,还有实现思路20.&nbsp;深浅拷贝的区别和手写深拷贝,讲实现思路反问了业务,反馈时间和学习建议二面基本上是围绕项目展开,根据项目的每一项,来给场景题问你会怎么做,跟基础相关的东西如下:1.&nbsp;虚拟列表的实现和原理2.&nbsp;zustand&nbsp;和&nbsp;context&nbsp;的区别3.&nbsp;vitest&nbsp;相关,写测试的话应该怎么做些什么?4.&nbsp;monorepo的细节问题5.&nbsp;做项目的动机6.&nbsp;事件委托和时间冒泡的区别有个点顺着问了我五个问题实在是答不下去了就是说感觉金山云这边面试虽然一面全是八股,但是二面还是要好好准备项目,做到能被深挖那么两三个问题的程度,鼠鼠也是运气很好,问的都是准备过的嘻嘻面试完之后还很期待这个面试官会不会是我mt或者ld,会很认真的听我说话,然后告诉我哪里有小问题,不知道是不是鼠鼠的错觉,感觉他看后辈的眼神都是带有欣赏的意味真的很复合我对mt/ld的幻想(bushi),但是后来发现他ip是北京的qwq有点点小失落,不过没关系,看隔壁某书感觉金山的节奏还挺慢的期待入职ing愿一切顺利,好运常伴吾身这里再吐槽一下流程,怎么!!这么!!慢!!急死我了急死我了!!鬼知道我从周一到接到offer这段时间有多煎熬,哎呀但是但是好在一切如愿
发面经攒人品
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务