首页 > 其他分享 >倍增思想复习

倍增思想复习

时间:2023-07-21 21:55:09浏览次数:40  
标签:www 复习 思想 int fat st LCA 倍增

倍增,st表复习

众所周知,st表是倍增思想的一种实现罢了

然后呢,倍增思想最重要应用于RMQ和LCA问题

都很重要,然而我还不会背,所以拿今晚一半时间左右来复习这个。
其实不用背,重在理解:
st表:注意先枚举2的多少次方(不然后面长的区间靠短的两个区间拼合,短的还没处理完的话是无法做的)
然后查询的时候要求左端点开始长度为k查一次,右端点长度为k向左查一次(其实就是找左端点而已)
为甚?因为我log2(r-l+1)是向下取整的,否则可能遍历不到。如果用大于k的会导致查询的区域过多而wa
https://www.luogu.com.cn/problem/P3865
https://www.luogu.com.cn/record/116834836

然后LCA:
https://www.luogu.com.cn/problem/P3379
https://www.luogu.com.cn/record/116834022
tarjan算法我是会的了,不再赘述,但是倍增算法非常有用,想查就查,而tarjan只能离线处理

首先只要会了st表,LCA就会一半了。fa(x,j)很好转移,一样是先向上跳一半,再跳一半这个意思
注意:由于我dfs到一个点,此时他之上的所有点都已经统计完了,所以进到这个点就立即计算数组,不会有问题的
关键是向上找的过程

首先是统一深度,深得那个点往上跳
然后再一起往上跳

注意三点:
1.还是因为log2是向下取整的,所以我不一定一次就能把深的点和浅的点统一深度
2.一起向上跳前,先判断下两者是不是到同一个点了
3.我向上跳还是由大到小这么跳,因此很有可能存在两个点跳过的情况,不能取这个答案
解决办法就是我尽力向上跳,两者要是跳到同一个点continue,那么最后两者能到的就是LCA 的两个儿子
return fa(x,0)即可

st代码:


	for(int j=0;j<=18;j++){//注意先美剧倍数
		for(int i=1;i<=n;i++){
			if(j==0){
				st[i][0]=num[i];
				continue;
			}
			else
				st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}	
	}
	while(m--){
		int l,r;
		l=read();
		r=read();
		//注,区间长度要求:l+2的x次方-1=R 
		//解得x=k=log2(r-l+1) 
		int k=log2(r-l+1);
		printf("%d\n",max(st[l][k],st[r-(1<<k)+1][k])) ;
	}

LCA重要函数:



void dfs(int x,int fa){
	fat[x][0]=fa;//注意初始化 
	for(int j=1;j<=19;j++){
		fat[x][j]=fat[fat[x][j-1]][j-1];//往上一半一半的跳 
	}//因为上面的都统计过了,所以现在dfs到这个点一定是可以统计的 
	dep[x]=dep[fa]+1;//这是为了后面lca好找 
	for(int i=0;i<mp[x].size();i++){
		int to=mp[x][i];
		if(to==fa){
			continue;
		}
		
		dfs(to,x);
	}
}
int getlca(int x,int y){
	if(dep[x]>dep[y]){
		swap(x,y);//注意不要swap dep数组了 ,x换到深的那里 
	}//让x在上方 
	for(int i=19;i>=0;i--){//还是一定要记住log2向下取整,所以不一定一次就可以跳到,这时候应该跳离depx最近的,所以从大到小美剧,而且每一次跳的比
	//上一次肯定少,所以一遍i即可 
	//另:从小到大枚举不就相当于一次走一位吗 
		if((dep[y]-(1<<i))>=dep[x]){
			y=fat[y][i];
		}
	}
	if(x==y){
		return x;
	}
	for(int i=19;i>=0;i--){
        if(fat[x][i]==fat[y][i])//因为可能都跳过了 
            continue;
        else{
        	x=fat[x][i];
			y=fat[y][i];
		}
            
    }
    return fat[x][0];
	
}


标签:www,复习,思想,int,fat,st,LCA,倍增
From: https://www.cnblogs.com/linghusama/p/17572475.html

相关文章

  • 扫描线小复习
    扫描线目录扫描线思想实现思想扫描线的思想十分简单,就是把矩形分为多次小的矩形求解罢了,关键在于实现记得有一次周考就写挂了......实现首先想要正好不重不漏地扫过一个矩形(只有一个的情况下)而不影响其他非矩形地方的方法是什么?假设我扫描线是从下往上扫的,那么对于这个矩形......
  • 铃狐sama的竞赛复习(持续更新)
    铃狐sama的竞赛复习计划目录铃狐sama的竞赛复习计划dfs,bfs的整体复习题目来源可如下:null数论复习,以下还要求掌握原理,暂时放在最后一起复习,记忆深刻一点gcd熟练掌握exgcd必须要求熟练背诵phi欧拉函数必须要求熟练背诵欧拉筛法必须要求熟练背诵卷积要求再进行熟练掌握整数分块要求......
  • 复习-基础课-基础算法
    1.快速排序:不稳定,其他略。2.归并排序:稳定,常用于求逆序对。voidmsort(intl,intr){if(l>=r)return;intmid=(l+r)>>1;msort(l,mid);msort(mid+1,r);//递归排序intk=0;inti=l,j=mid+1;while(i<=mid&&j<=......
  • 搜索和图论_复习
    DFSAcWing842.排列数字代码#include<bits/stdc++.h>usingnamespacestd;typedefpair<int,int>PII;constintN=10;intpath[N];boolst[N];intn;voiddfs(intx){if(x>n)return;for(inti=1;i<=n;i++){if(st[i]==1)continu......
  • js黑客思想(1)
    十六进制  十六进制,它只在字符串内部起作用,如果您尝试将其用作标识符,他们将失败。一个有趣的方面是,十六进制转义必须使用小写的x,如果使用大写的X,它将不会被视为十六进制转义,js引擎将简单地将字符串处理为字面上的大写X,后面跟着你指定的字符。'\x61'//a"\x61"//a`\x61......
  • 笔试复习
    NOI2023是第40届,IOI2000是第12届,在北京。kill仅对PID生效,killall用于进程名字。删除目录:rm-r。linux区分大小写。查看隐藏文件:ls-a。高级语言的程序是源程序,不是源代码!只编译生成目标文件的命令行选项是:-c。指定输出文件名的命令行选项是:-o。在Linux的各个......
  • 复习结构体的创建,重定义,打印,以及对函数压栈的理解
    函数在操作,在栈上进行,形参的拷贝和函数的运行,基本上都在栈上完成,所以结构体的传参,对栈区的资源消耗较大。而传地址的操作则会节省栈区资源,不需要形参的拷贝过程,而是直接寻址。#define_CRT_SECURE_NO_WARNINGS1#include"stdio.h"structT{ chart; chars;};typedefstruc......
  • 《尚书》的中心思想与对个人的建议
    中国古代《尚书》的中心思想是什么,表达了什么政治理想和主张,对个人的生活与成长有哪些建议中国古代《尚书》的中心思想是君主专制和礼制。这部经典表达了尊王攘夷、尊儒抑法的政治理想和主张。《尚书》强调了君主的权威和地位,主张君主应该是万民的统治者,并且君主具有神圣的地位,......
  • 《诗经》的中心思想与对个人的建议
    中国古代《诗经》的中心思想是什么,表达了什么政治理想和主张,对个人的生活与成长有哪些建议中国古代《诗经》的中心思想是崇尚美德、尊重人伦关系和推崇君主德政。这部经典表达了君主德政、社会和谐以及个人修养的政治理想和主张。《诗经》中强调了君主的德政。诗中描述了君主应......
  • NOI 2023 考前知识点总复习
    NOI2023考前知识点总复习其实就是把熟悉或不熟悉的东西再过一遍,防止考场上出现会了做法却因为忘了算法而写不出来的问题。可能会一句话概括,也可能附上一点代码片段。如果不想复习知识点,只想要一点考前提示,可以直接翻到本文最底部。目录I.数据结构、树上问题II.数论III.......