首页 > 其他分享 >P7974 题解

P7974 题解

时间:2023-10-18 22:34:02浏览次数:29  
标签:limits P7974 题解 cin times int max ST

解题思路

首先可以确保每一次列的方向一定不会与 \(s\) 到 \(t\) 的方向相反。

不妨设 \(l=\min\{s,t\}\),\(r=\max\{s,t\}\)。

对于每次移动,所花体力值如下:

显然,从 \(l\) 到 \(r\),一定要翻过 \([l,r]\) 间最高的一个,区间最大我们毫不犹豫地选择 ST 表,然后我们思考一下,令 \(h_x=\max\limits_{i\in[l,r]}\{h_i\}\),那么从 \((l,h_l)\) 到 \((x,h_x)\),一定至少花费 \(4\times\max\limits_{i\in[l,r]}\left\{h_i-(h_l+i-l)\right\}=4\times(\max\limits_{i\in[l,r]}\{h_i-i\}-(h_l-l))\) 体力值,所以再用一个 ST 表维护 \(h_i-i\) 的区间最大值。

同理,从 \((r,h_r)\) 至 \((x,h_x)\) 也需要用一个 ST 表维护 \(h_i+i\) 的区间最大值。

令 \(a\) 为 \(\max\limits_{i\in[l,r]}\{h_i\}\),\(b\) 为 \(\max\limits_{i\in[l,r]}\{h_i-i\}\),\(c\) 为 \(\max\limits_{i\in[l,r]}\{h_i+i\}\),则最后的答案为为 \(a - 4\times h_s - h_t + 2 \times (b + c)\),注意是 \(s,t\),不是 \(l,r\)!!!(因为如果是 \(l,r\) 则询问 \(s,t\) 与 \(t,s\) 所得到的答案是一样的,但显然不同)

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, a[N], f[N][20][3];
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		f[i][0][0] = a[i];
		f[i][0][1] = a[i] - i;
		f[i][0][2] = a[i] + i;
	}
	for(int i = 1; i <= 19; i++) {
		for(int j = 1; j + (1 << (i - 1)) <= n; j++) {
			f[j][i][0] = max(f[j][i - 1][0], f[j + (1 << (i - 1))][i - 1][0]);
			f[j][i][1] = max(f[j][i - 1][1], f[j + (1 << (i - 1))][i - 1][1]);
			f[j][i][2] = max(f[j][i - 1][2], f[j + (1 << (i - 1))][i - 1][2]);
		}
	}
	int q;
	cin >> q;
	while(q--) {
		int s, t, s1, t1;
		cin >> s >> t;
		s1 = s, t1 = t;
		if(s > t) {
			swap(s, t);
		}
		int k = log2(t - s + 1);
		int a1 = max(f[s][k][0], f[t - (1 << k) + 1][k][0]);
		int b1 = max(f[s][k][1], f[t - (1 << k) + 1][k][1]);
		int c1 = max(f[s][k][2], f[t - (1 << k) + 1][k][2]);
		cout << a1 - 4 * a[s1] - a[t1] + 2 * (b1 + c1) << '\n';
	}
	return 0;
}

标签:limits,P7974,题解,cin,times,int,max,ST
From: https://www.cnblogs.com/cyf1208/p/17773536.html

相关文章

  • P4814 题解
    解题思路对于每条边\((u,v)\),权值为\(w\),假设存在一条经过这一条边的路径,其最短距离为\(a\)到\(u\)的最短路加上\(v\)到\(b\)的最短距离加上\(w\),若这个值都大于\(d\),则不可能关闭这条边。由于边权非负,所以可采用dijkstra来处理最短路。因为为有向边,所以可以再建......
  • C++常见入门题题解
    前言因为本人目前比较菜,所以给出的题解都是按照自己的学习进度来的,所以难度是一个循序渐进的过程,由于本人水平有限,望读者能够指出谬误,共同进步。回文数输出#include<bits/stdc++.h>//万能头usingnamespacestd;intmain(void){vector<int>font;//定义一个整型的向......
  • 题解 CF1651F【Tower Defense】
    题解CF1651F【TowerDefense】problem一个塔防游戏。一共有\(n\)个塔按\(1\simn\)的顺序排成一列,每座塔都有魔力容量\(c_i\)和魔力恢复速率\(r_i\)。对于一座塔\(i\),每过一秒它的魔力\(m_i\)会变为\(\min(m_i+r_i,c_i)\)。每座塔初始时满魔力。一共有\(q\)个......
  • 【题解 CF840C & P4448】 On the Bench & 球球的排列
    OntheBench题面翻译给定一个序列\(a(a_i\le10^9)\),长度为\(n(n\le300)\)。试求有多少\(1\)到\(n\)的排列\(p_i\),满足对于任意的\(2\lei\len\)有\(a_{p_{i-1}}\timesa_{p_i}\)不为完全平方数,答案对\(10^9+7\)取模。题目描述Ayearagoonthebenchinpu......
  • P9506 题解
    blog。Firstsolution/kx。容易想到断环成链。打开标签发现是DP,于是就可以DP了。code,时间复杂度\(O(\text{能过})\)。......
  • 算法笔记-有效括号序列题解
    描述给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列。括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。数据范围:字符串长度0≤n≤10000要求:空间复杂度O(n),时间复杂......
  • NOIP2018PJ T3 摆渡车(2023.10第二版题解)
    题目链接 题意:时间轴上分布着$n$位乘客($1\len\le500$),$i$号乘客的位置为$t_i$(0\let_i\le4\times10^6),用互相距离不小于$m$的车次将时间轴分为若干部分,并管辖以自己为右端点的这个区间(除了第一趟车包括$0$,其他车次左开右闭),求最小费用和。每个车次的费用来自:管辖区间内所......
  • AT_arc100_b 题解
    题意这道题是让我们把一段区间分成四个不为空的连续子序列,并算出每个区间的和,最后用四个和的最大值减去最小值,算出最终答案。分析大家首先想到的肯定是暴力法用三个循环枚举四个区间,对于每一个区间,在单独算和,这样的时间复杂度$O(n^4)$,肯定会超时。现在我们进行优化:最后求和的......
  • P4899 [IOI2018] werewolf 狼人 题解
    P4899[IOI2018]werewolf狼人题解题目描述省流:\(n\)个点,\(m\)条边,\(q\)次询问,对于每一次询问,给定一个起点\(S\)和终点\(T\),能否找到一条路径,前半程不能走\(0\thicksimL-1\)这些点,后半程不能走\(R+1\thicksimN-1\)这些点。中途必须有一个点在\(L\thicksimR\)之......
  • AT_abc134_d Preparing Boxes题解
    简述题意这什么破翻译,看了AtCoder的英文才看懂。给定一个长度为\(n\)序列\(a\),要求构造一个数列\(b\),使得对于任意\(i\),满足:\(1\lei\len\)将\(b\)序列下标为\(i\)的倍数的值相加使得这个总和模2等于\(a_i\)。求序列\(b\)中值为1的个数与值为1......