炸鸡块君与FIFA22(倍增 + ST表)

news/2024/10/17 16:24:26/

2022牛客寒假算法基础集训营1
在这里插入图片描述

ST表

倍增二进制划分相结合可以降低很多题目的算法复杂度。主要常见的应用为求区间最值问题(RMQ)的ST表,以及求解最近公共祖先(LCA)的树上倍增思想。
以下总结的关于RMQ问题的思想。

功能

O(1)时间复杂度内在线回答数组中在下标 [ l , r ] [l, r] [l,r]之间的数最大值为多少。但是需要NlogN的时间预处理。

定义

f [ i , j ] : 表示数列 A 中下标在区间 [ i , i + 2 j − 1 ] 里的数的最大值,也就是从 i 开始的 2 j 个数的最大值。 f[i, j] : 表示数列A中下标在区间[i, i + 2^j - 1]里的数的最大值,也就是从i开始的2^j个数的最大值。 f[i,j]:表示数列A中下标在区间[i,i+2j1]里的数的最大值,也就是从i开始的2j个数的最大值。
递推边界: f [ i , 0 ] = A [ i ] f[i, 0] = A[i] f[i,0]=A[i]

状态转移方程

f [ i , j ] = m a x ( f [ i , j − 1 ] , f [ i + 2 j − 1 , j − 1 ] ) f[i, j] = max(f[i, j - 1], f[i + 2^{j - 1}, j - 1]) f[i,j]=max(f[i,j1],f[i+2j1,j1])
f [ i ] [ j ] = m a x ( f [ i ] [ j − 1 ] , f [ i + ( 1 < < ( j − 1 ) ) ] [ j − 1 ] ) ; f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); f[i][j]=max(f[i][j1],f[i+(1<<(j1))][j1]);
即长度为 2 j 2^j 2j 的的区间的最大值等于左右两个长度为 2 j − 1 2^{j - 1} 2j1的区间的最大值中较大的一个。

查询

当查询任意区间的最值时,我们需要先计算出一个满足以下条件的k值, 2 k ≤ r − l + 1 < 2 k + 1 2^k \leq r- l + 1 < 2^{k + 1} 2krl+1<2k+1,也即使2的次幂小于区间长度的同时尽量大的一个k值。

代码

	int n; cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];for (int i = 1; i <= n; i++) f[i][0] = a[i];int t = log(n) / log(2) + 1;//mp数组记录长度为j的区间对应的k值for (int i = 0; i <= t; i++)for (int j = 1 << i; j < min(n + 1, 1 << (i + 1)); j++)mp[j] = i;for (int j = 1; j < t; j++)for (int i = 1; i <= n - (1 << j) + 1; i++)f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);int q; cin >> q;while (q--){int l, r; cin >> l >> r;int k = mp[r - l + 1];cout << max(f[l][k], f[r - (1 << k) + 1][k]) << endl;}

拓展(二维RMQ问题)

有两种方法

  1. f [ i ] [ j ] [ k ] : 以点 ( i , j ) 为左上角坐标,边长为 2 k 的矩阵中的最值 f[i][j][k]: 以点(i, j)为左上角坐标,边长为 2^k 的矩阵中的最值 f[i][j][k]:以点(i,j)为左上角坐标,边长为2k的矩阵中的最值
    f [ i ] [ j ] [ k ] = f [ i ] [ j ] [ k − 1 ] + f [ i + ( 1 < < ( k − 1 ) ) ] [ j ] [ k − 1 ] + f [ i ] [ j + ( 1 < < ( k − 1 ) ) ] [ k − 1 ] + f [ i + ( 1 < < ( k − 1 ) ) ] [ j + ( 1 < < ( k − 1 ) ) ] [ k − 1 ] f[i][j][k] = f[i][j][k - 1] +\\ f[i + (1 << (k - 1))][j][k - 1] + \\ f[i][j + (1 << (k - 1))][k - 1] +\\ f[i + (1 << (k - 1))][j + (1 << (k - 1))][k - 1] f[i][j][k]=f[i][j][k1]+f[i+(1<<(k1))][j][k1]+f[i][j+(1<<(k1))][k1]+f[i+(1<<(k1))][j+(1<<(k1))][k1]类似于二维区间前缀和, 其实就是一个 “田”字, 一次查询即为答案,时间复杂度 O ( 1 ) O(1) O(1)

  2. f [ i ] [ j ] [ k ] : 第 i 行,区间 [ j , j + 2 k − 1 ] 中的最值 f[i][j][k]:第i行,区间[j, j + 2^k - 1]中的最值 f[i][j][k]:i行,区间[j,j+2k1]中的最值
    转移方程与一般的ST表一样,只是多了一维。一次查询需要循环k次, 时间复杂度 O ( k ) O(k) O(k)


Solution

很明显,对于模3相等的初始值,其相同区间的分数变化量相同。所以我们只需要分别求出初始值为0, 1, 2时所有子区间各自对应的区间和即可。详细细节见下面的代码。

Code

const int N = 3e5 + 5;
int cnt = 0;
int f[3][N][20];//注意数组越界
int mp[N];int main()
{IOS;int n, q; cin >> n >> q;string s; cin >> s;s = " " + s;int t = log(n) / log(2) + 1;for (int i = 0; i < t; i++)for (int j = 1 << i; j < 1 << (i + 1); j++)mp[j] = i;//注意数组越界assert(1 << t < 3e5);for (int k = 0; k < 3; k++)for (int j = 1; j <= n; j++)if (s[j] == 'W') f[k][j][0] = 1;else if (s[j] == 'L' && k) f[k][j][0] = -1;for (int j = 1; j < t; j++)for (int i = 1; i <= n - (1 << j) + 1; i++){int p = i + (1 << (j - 1));f[0][i][j] = f[0][i][j - 1] + f[(0 + f[0][i][j - 1]) % 3][p][j - 1];f[1][i][j] = f[1][i][j - 1] + f[(1 + f[1][i][j - 1]) % 3][p][j - 1];f[2][i][j] = f[2][i][j - 1] + f[(2 + f[2][i][j - 1]) % 3][p][j - 1];//假设第一维的值为k//注意:不能像上面的预处理一样单独循环三遍不同的k,因为当前状态的k可能会用到不同k值的状态}int l, r, p;while (q--){int ans;cin >> l >> r >> ans;//倍增思想的应用while (l <= r){ans += f[ans % 3][l][mp[r - l + 1]];l += 1 << mp[r - l + 1];}cout << ans << endl;}return 0;
}

http://www.ppmy.cn/news/802471.html

相关文章

xp系统steam无法连接到更新服务器,xp系统打不开steam提示“无法链接至steam网络”的处理办法...

今天和大家分享一下xp系统打不开steam提示“无法链接至steam网络问题的解决方法&#xff0c;在使用xp系统的过程中经常不知道如何去解决xp系统打不开steam提示“无法链接至steam网络的问题&#xff0c;有什么好的办法去解决xp系统打不开steam提示“无法链接至steam网络呢&#…

hgame2023-week2

hgame2022-week2 web Git Leakage githack 直接就看见了 v2board [V2Board Admin.php 越权访问漏洞 | PeiQi文库](http://wiki.peiqi.tech/wiki/webapp/V2Board/V2Board Admin.php 越权访问漏洞.html) Reverse before_main 换表base64 你直接看的表不一定是真的 math …

【CE实战】Clicker Heroes 快速通关

导读 真爱生命&#xff0c;远离无节制游戏。 以前在游戏公司待过&#xff0c;在正式服玩很久的游戏&#xff0c;开发环境下&#xff0c;使用GM命令就能一刀99999999&#xff0c;从此很少玩游戏。对于单机游戏更是如此&#xff0c;今天就为大家介绍一款特肝的游戏&#xff1a;Cl…

SteamVR 错误代码 108 / 203 / 208 / 301 / 306 / 308 / 400 / 405 排解方法

【ERROR&#xff08;108&#xff09;未找到头戴式显示器】排除方式 这项错误可能是一个 USB 或驱动程式出了问题。请尝试以下问题排解步骤&#xff1a; 1. 重新启动你的头戴显示器&#xff1a; A. 在 SteamVR 内用右键点击头戴显示器的图示。 B. 选择“重新启动 VIVE 头戴…

steam进社区显示服务器错误,Steam错误代码-118怎么办 社区打不开解决方法

steam是不少玩家在玩游戏时常常会使用到的游戏商城&#xff0c;但是近日很多玩家出现在启动steam的时候出现错误代码-118&#xff0c;社区打不开连接不上商店&#xff0c;那么遇到这种情况应该怎么呢&#xff0c;不用着急&#xff0c;今天UU就为大家带来了出现错误代码-118的解…

打不开Microsoft store 解决方法

打不开Microsoft store 解决方法 方法一&#xff1a; 按 “windows键 R” 打开 “运行” 窗口&#xff1a;输入 inetcpl.cpl 后点确定 点击 “高级” 勾选上 “使用TLS 1.2” 或者 点击 “还原高级设置” 注意&#xff1a;选一个就行&#xff01; 再次打开 微软商店&am…

Epic Games Launcher的安装、解决打开失败问题、插件下载问题

本博客讲述了 Epic Games Launcher的安装步骤&#xff0c;安装过程中遇到的问题以及插件下载问题。 下载Epic Games Launcher压缩包&#xff0c;可以通过下面的地址进行下载 https://www.epicgames.com/store/en-US/download2. 解压、安装&#xff0c;之后会在桌面上看到Epic …

杀戮尖塔java打不开,救救萌新!我steam平台,已经订阅Java的mod,可是打不开啊!!!...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这是我进去显示的到这就卡了 Running with debug mode turned ON...ModVersion Info: - Java version (1.8.0_144) - Slay the Spire (01-23-2019) - ModTheSpire (3.10.1) Mod list: - IsaacMod (1.2.13)Begin patching... Patch…