题目链接:
题目
输入
输入文件名为。
第一行一个整数。
接下来一行个整数,描述序列。
第三行一个数 。
接下来行,每行三个整数。其中第一个整数表示操作的类型。对应修改操作, 对应查询操作。
输出
输出文件名为。
对于每个查询,给出 。
样例输入1
6
90 50 78 0 96 20
6
0 1 35
1 1 4
0 1 67
0 4 11
0 3 96
1 3 5
样例输出1
78
85
样例输入2
50
544 944 200 704 400 150 8 964 666 596 850 608 452 103 988 760 370 723 350 862 856 0 724 544 668 891 575 448 16 613 952 745 990 459 740 960 752 194 335 575 525 12 618 80 618 224 240 600 562 283
10
1 6 6
1 1 3
0 11 78279
0 33 42738
0 45 67270
1 1 26
1 19 24
1 37 39
1 8 13
0 7 64428
样例输出2
0
744
77683
856
558
77683
数据范围
对于的数据,
对于的数据,
对于的数据,
思路
这道题是线段树。
我们先判断怎么处理查询操作。
通过证明我们可以得出查询的最优答案一定是选择两个相邻的数。
具体证明看这位大佬的博客==>
那剩下的就简单了,就线段树咯。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n, a[100001], b[100001], tree[800001], q, x, y, z, ans;
void build(int now, int l, int r) {//建树
if (l == r) {
tree[now] = b[l];
return ;
}
int mid = (l + r) >> 1;
build(now << 1, l, mid);
build(now << 1 | 1, mid + 1, r);
tree[now] = max(tree[now << 1], tree[now << 1 | 1]);
}
void getans(int now, int l, int r, int wl, int wr) {//求值
if (l == wl && r == wr) {
ans = max(ans, tree[now]);
return ;
}
int mid = (l + r) >> 1;
if (wr <= mid) getans(now << 1, l, mid, wl, wr);
else if (wl > mid) getans(now << 1 | 1, mid + 1, r, wl, wr);
else {
getans(now << 1, l, mid, wl, mid);
getans(now << 1 | 1, mid + 1, r, mid + 1, wr);
}
}
void change(int now, int l, int r, int wh, int val) {//改值
if (l == r) {
tree[now] = val;
return ;
}
int mid = (l + r) >> 1;
if (wh <= mid) change(now << 1, l, mid, wh, val);
else change(now << 1 | 1, mid + 1, r, wh, val);
tree[now] = max(tree[now << 1], tree[now << 1 | 1]);
}
int main() {
// freopen("lipschitz.in", "r", stdin);
// freopen("lipschitz.out", "w", stdout);
scanf("%d", &n);//读入
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);//读入
b[i - 1] = abs(a[i] - a[i - 1]);//求相邻数的绝对值
}
build(1, 1, n - 1);//建树
scanf("%d", &q);//读入
for (int Q = 1; Q <= q; Q++) {
scanf("%d %d %d", &x, &y, &z);//读入
if (x) {//求值
ans = 0;
if (y != z) getans(1, 1, n - 1, y, z - 1);
printf("%d\n", ans);//输出
}
else {//改值
a[y] = z;
b[y - 1] = abs(a[y] - a[y - 1]);//修改会牵连到两个
b[y] = abs(a[y + 1] - a[y]);
change(1, 1, n - 1, y - 1, b[y - 1]);
change(1, 1, n - 1, y, b[y]);
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}