Line Segment tree of BZOJ 3922 Karin
Theme
A sequence is provided, which supports single-point modification. Each query sets a single bit to the maximum values in the arithmetic difference series.
Ideas
If the tolerances of an equal-difference series are large, there will not be many numbers in the entire series. However, if the tolerances are small, we can use the line segment tree to mess up. The specific method is to maintain a line segment tree for each tolerance and divide it according to the modulo value of the tolerance. In this way, the query is complete.
For more information, see the code.
CODE
#define _CRT_SECURE_NO_WARNINGS#include
#include
#include
#include #define MAX 70010#define INF 0x3f3f3f3fusing namespace std;#define LEFT (pos << 1)#define RIGHT (pos << 1|1)int cnt, asks;int src[MAX];int tree[55][MAX << 2];int shine[55][MAX];int _src[55][MAX];int _end[55][55];void BuildTree(int tree[], int src[], int l, int r, int pos){ if(l == r) { tree[pos] = src[l]; return ; } int mid = (l + r) >> 1; BuildTree(tree, src, l, mid, LEFT); BuildTree(tree, src, mid + 1, r, RIGHT); tree[pos] = max(tree[LEFT], tree[RIGHT]);}void Modify(int tree[], int l, int r, int x, int c, int pos){ if(l == r) { tree[pos] += c; return ; } int mid = (l + r) >> 1; if(x <= mid) Modify(tree, l, mid, x, c, LEFT); else Modify(tree, mid + 1, r, x, c, RIGHT); tree[pos] = max(tree[LEFT], tree[RIGHT]);}int Ask(int tree[], int l, int r, int x, int y, int pos){ if(l == x && y == r) return tree[pos]; int mid = (l + r) >> 1; if(y <= mid) return Ask(tree, l, mid, x, y, LEFT); if(x > mid) return Ask(tree, mid + 1, r, x, y, RIGHT); int left = Ask(tree, l, mid, x, mid, LEFT); int right = Ask(tree, mid + 1, r, mid + 1, y, RIGHT); return max(left, right);}int main(){ cin >> cnt; for(int i = 1; i <= cnt; ++i) scanf("%d", &src[i]); int range = min(4, cnt); for(int i = 1; i <= range; ++i) { int now = 0; for(int j = 1; j <= i; ++j) { for(int k = j; k <= cnt; k += i) { shine[i][k] = ++now; _src[i][now] = src[k]; } _end[i][j] = now; } BuildTree(tree[i], _src[i], 1, cnt, 1); } cin >> asks; for(int flag, x, y, i = 1; i <= asks; ++i) { scanf("%d%d%d", &flag, &x, &y); if(!flag) { src[x] += y; for(int j = 1; j <= range; ++j) Modify(tree[j], 1, cnt, shine[j][x], y, 1); } else { if(y <= range) printf("%d\n", Ask(tree[y], 1, cnt, shine[y][x], _end[y][x % y ? x % y:y], 1)); else { int ans = -INF; for(int j = x; j <= cnt; j += y) ans = max(ans, src[j]); printf("%d\n", ans); } } } return 0;}
I don't know why. If we open the 2D _ end array into MAX, we will RE.
Which of the following gods knows how to tell me...