当前位置: 首页 > news >正文

倍增练习(1)

A - ST 表 && RMQ 问题

 

题目思路:st表的板子题用于静态区间求最值,通过倍增的思想,先通过预处理将各个区间的最大值通过转移式求出f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);然后再进行重叠查询查询,k = log2(r - l + 1);,max(f[l][k], f[r - (1 << k) + 1][k]).

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define N 2000005
typedef long long ll;
ll n, m, t, a, b, c, k, d, r, l;
ll f[N][32], dp[N];
ll ans, maxx, minn = 1e9;
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
	return x * f;
}
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++) f[i][0] = read();
	for (int j = 1; j <= 20; j++) {
		for (int i = 1; i + (l << j) - 1 <= n; i++) {
			f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
		}
	}
	for (int i = 1; i <= m; i++) {
		l = read(), r = read();
		k = log2(r - l + 1);
		cout << max(f[l][k], f[r - (1 << k) + 1][k]) << '\n';
	}
	return 0;
}

P3379 【模板】最近公共祖先(LCA)

 

题目思路:dep[u]存u点的深度,f[u][i]存从u点向上提哦啊2^i层的祖先节点,首先通过dfs进行倍增递推打表,从小到大枚举,然后跑一边lca进行二进制拆分,从大到小枚举.用快读读取,卡时间

代码实现:

#include<bits/stdc++.h>
using namespace std;
#define N 2000005
typedef long long ll;
ll n, m, t, a, b, c, k, d, r, l;
ll f[N][30], dep[N];
ll ans, maxx, minn = 1e9;
vector<ll>v[N];
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
	return x * f;
}
void dfs(ll u, ll father) {
	dep[u] = dep[father] + 1;
	f[u][0] = father;
	for (int i = 1; i <= 20; i++) {
		f[u][i] = f[f[u][i - 1]][i - 1];
	}
	for (ll v : v[u]) {
		if (v != father)
			dfs(v, u);
	}
}

ll lca(ll u, ll v) {
	if (dep[u] < dep[v]) swap(u, v);
	for (int i = 20; i >= 0; i--)
		if (dep[f[u][i]] >= dep[v])
			u = f[u][i];
	if (u == v) return v;
	for (int i = 20; i >= 0; i--) {
		if (f[u][i] != f[v][i])
			u = f[u][i], v = f[v][i];
	}
	return f[u][0];
}
int main()
{
	cin >> n >> m >> t;
	for (int i = 1; i <= n-1; i++) {
		a = read(), b = read();
		v[a].push_back(b), v[b].push_back(a);
	}
	dfs(t, 0);
	for (int i = 1; i <= m; i++) {
		a = read(), b = read();
		cout << lca(a,b) << '\n';
	}
	return 0;
}

相关文章:

  • 【win工具】win安装flameshot并设置截图快捷键
  • C++ | Leetcode C++题解之第415题字符串相加
  • 微软九月补丁星期二发现了 79 个漏洞
  • 【CSS Tricks】在css中尝试一种新的颜色模型HSL
  • 向日葵好用吗?4款稳定的远程控制软件推荐。
  • C++ : 继承问题 [virtual函数调用,为什么禁止在virtual使用默认参数]
  • 深入探讨IDSIPS:信息安全的未来趋势与应用
  • Python | Leetcode Python题解之第401题二进制手表
  • 代码管理-使用TortoiseGit同步项目到Github/Gitee
  • 近期值得关注的3个线性时序模型及其未来发展综述
  • html加载页面
  • XWiki中添加 html 二次编辑失效
  • C++初阶学习第六弹------标准库中的string类
  • 微信小程序页面制作——婚礼邀请函(含代码)
  • linux 解压缩
  • sql server 分区表查询
  • Android 12系统源码_窗口管理(八)WindowConfiguration的作用
  • springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)
  • 二叉树的链式结构和递归程序的递归流程图
  • JavaScript substring() 方法
  • 商务部新闻发言人就出口管制管控名单答记者问
  • 国际能源署:全球电动汽车市场强劲增长,中国市场继续领跑
  • 中巴续签双边本币互换协议,进一步深化金融战略合作
  • 2024年度全国秋粮收购达3.45亿吨
  • 1至4月全国铁路完成固定资产投资1947亿元,同比增长5.3%
  • 可量产9MWh超大容量储能系统亮相慕尼黑,宁德时代:大储技术迈入新时代