题目链接 Drazil and Park

中文题面 传送门

如果他选择了x和y,那么他消耗的能量为dx + dx + 1 + ... + dy - 1 + 2 * (hx + hy).

把这个式子写成这个形式

(d1 + d2 + ... + dy - 1 + 2 * hy) + (2 * hx - (d1 + d2 + ... + dx - 1))

令(2 * hk - (d1 + d2 + ... + dk - 1)) = Lk 

   (d1 + d2 + ... + dk - 1 + 2 * hk) = Rk

我们在查询的时候,就要在[a, b]内找到u, v 使得L[u] + R[v] 最大

而当 u < v 的时候,总有 L[u] + R[v] > L[v] + R[u]

那我们放心地在[a, b]这个区间内找u和v,使L[u]和R[v]分别为这段区间上的最大值

这个过程用ST表维护即可。

但是我们要注意u = v的情况,也就是说求出来的u和v可能相等。

而题目的要求是u和v必须不相等

那么这个时候我们分类讨论一下,把[a, b]在u这一点分割成两个区间,在[a, u - 1]和[u + 1, b]里去找v

同理把[a, b]在v这一点分割成两个区间,在[a, v - 1]和[v + 1, b]里去找u

问题就这么解决了

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL;
typedef pair <LL, int> PII; const int N = 2e5 + 10;
const int A = 19; int n, m;
LL d[N], h[N], s[N];
PII x[N], y[N], f[N][A], g[N][A];
int L, R;
int et; void ST(){
rep(i, 1, n) f[i][0] = x[i];
rep(j, 1, 18)
rep(i, 1, n)
if ((i + (1 << j) - 1) <= n) f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]); rep(i, 1, n) g[i][0] = y[i];
rep(j, 1, 18)
rep(i, 1, n)
if ((i + (1 << j) - 1) <= n) g[i][j] = max(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]);
} inline PII Xmax(int l, int r){
if (l > r) return make_pair(-1e18, 0);
int k = (int)log2((double)(r - l + 1));
return max(f[l][k], f[r - (1 << k) + 1][k]);
} inline PII Ymax(int l, int r){
if (l > r) return make_pair(-1e18, 0);
int k = (int)log2((double)(r - l + 1));
return max(g[l][k], g[r - (1 << k) + 1][k]);
} LL solve(int l, int r){
PII n1 = Xmax(l, r), n2 = Ymax(l, r);
if (n1.second != n2.second) return n1.first + n2.first;
PII n3 = max(Ymax(l, n1.second - 1), Ymax(n1.second + 1, r));
PII n4 = max(Xmax(l, n2.second - 1), Xmax(n2.second + 1, r));
return max(n1.first + n3.first, n2.first + n4.first);
} int main(){ scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%lld", d + i);
rep(i, 1, n) scanf("%lld", h + i); rep(i, n + 1, n << 1) d[i] = d[i - n];
rep(i, n + 1, n << 1) h[i] = h[i - n]; rep(i, 2, n << 1) s[i] = s[i - 1] + d[i - 1];
rep(i, 1, n << 1) x[i] = make_pair(2 * h[i] + s[i], i);
rep(i, 1, n << 1) y[i] = make_pair(2 * h[i] - s[i], i); et = n;
n <<= 1;
ST();
n = et; while (m--){
int l, r;
scanf("%d%d", &l, &r);
if (r >= l) L = r + 1, R = l - 1 + n; else L = r + 1, R = l - 1;
printf("%d %d\n", L, R);
printf("%lld\n", solve(L, R));
} return 0;
}

Codeforces 515E Drazil and Park (ST表)的更多相关文章

  1. Codeforces 475D 题解(二分查找+ST表)

    题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...

  2. Codeforces 873E Awards For Contestants ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9255885.html 题目传送门 - CF873E 题意 现在要给 $n(n\leq 3000)$ 个学生颁奖 ...

  3. Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

    思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 els ...

  4. CodeForces 516C Drazil and Park 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...

  5. codeforces 516c// Drazil and Park// Codeforces Round #292(Div. 1)

    题意:一个圆环上有树,猴子上下其中一棵树,再沿着换跑,再上下另一棵树.给出一个区间,问最大的运动距离是. 给出区间大小dst,和数高数组arr. 设区间[x,y],a[x]=2*arr[x]+dst[ ...

  6. Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树

    C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...

  7. ST表入门学习poj3264 hdu5443 hdu5289 codeforces round #361 div2D

    ST算法介绍:[转自http://blog.csdn.net/insistgogo/article/details/9929103] 作用:ST算法是用来求解给定区间RMQ的最值,本文以最小值为例 方 ...

  8. Codeforces Round #422 (Div. 2)E. Liar sa+st表+dp

    题意:给你两个串s,p,问你把s分开顺序不变,能不能用最多k段合成p. 题解:dp[i][j]表示s到了前i项,用了j段的最多能合成p的前缀是哪里,那么转移就是两种,\(dp[i+1][j]=dp[i ...

  9. 【CodeForces】713 D. Animals and Puzzle 动态规划+二维ST表

    [题目]D. Animals and Puzzle [题意]给定n*m的01矩阵,Q次询问某个子矩阵内的最大正方形全1子矩阵边长.n,m<=1000,Q<=10^6. [算法]动态规划DP ...

随机推荐

  1. sstable, bigtable,leveldb,cassandra,hbase的lsm基础

    先看懂文献1和2 1. 先了解sstable.SSTable: Sorted String Table [2] [10] WiscKey:  类似myisam, key value分离, 根据ssd优 ...

  2. 组合的输出(DFS)

    题目描述: 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r<=n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数. 现要求你用递归的方法输出 ...

  3. [LUOGU] P1024 选课

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  4. perl学习之内置变量

    Perl内置特殊变量   一.正则表达式特殊变量:1.$n  :包含上次模式匹配的第n个子串2.$& :前一次成功模式匹配的字符串3.$`  :前次匹配成功的子串之前的内容4.$’ :前次匹配 ...

  5. LeetCode 653. Two Sum IV – Input is a BST

    Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...

  6. BZOJ 4504: K个串

    题目大意: 求一个序列的第k大的子串和. 题解: 对于一个右端点找最优的左端点,扔进堆里. 每次取堆顶,将这个右端点可以选择的左端点的区间分成两段,扔进堆里,重复k次. 现在需要对于一个固定的右端点, ...

  7. C# 字符串型转数字型

    // 当需要将字符串格式的数字转为数字时候,我们会用到的函数为Convert.ToDouble(),// 然而当你的字符串为49,9时,由于包含了逗号,函数会将逗号忽略,直接转为499,// 所以我们 ...

  8. vim 第三章 插入模式

    vim 第三章  插入模式 在普通模式下可以删除  复制   及粘贴的命令    在插入模式下也存在以中方便快捷的方式    能够粘贴寄存器中文本   两种方式来插入键盘上不存在的非常用字符 替换模式 ...

  9. 【JavaScript 5—基础知识点】:正则表达式(笔记)

    一.总体概览 1.1,什么是正则 又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符 ...

  10. js对文字进行编码

    js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent 1 ...