題目鏈接:
題目
輸入
輸入文件名爲。
第一行一個整數。
接下來一行個整數,描述序列。
第三行一個數 。
接下來行,每行三個整數。其中第一個整數表示操作的類型。對應修改操作, 對應查詢操作。
輸出
輸出文件名爲。
對於每個查詢,給出 。
樣例輸入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;
}