Description:
单点修改,询问区间是否构成公差为
k
k
的等差数列。
Solution:
公差为的等差数列可以改成以下性质:
1
1
.相邻两项差的
2
2
.最大值与最小值的差为
3
3
.区间内没有相同的数
所以第一项维护差的,维护区间最大最小值,第三项给每个权值开个平衡树,记录每个权值上次出现的位置
pre
p
r
e
,每次查询
pre
p
r
e
最小值,如果
<l
<
l
<script type="math/tex" id="MathJax-Element-154">
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
struct node {
int mx, mn, gcd, pre;
} t[maxn * 4];
int n, m, last, id;
int a[maxn];
set<int> s[maxn * 2];
map<int, int> mp;
int read() {
int x = 0, f = 1;
char c = getchar();
while(!isdigit(c)) {
if(c == '-') {
f = -1;
}
c = getchar();
}
while(isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
void build(int l, int r, int x) {
if(l == r) {
t[x].mx = t[x].mn = a[l];
t[x].gcd = abs(a[l] - a[l - 1]);
return;
}
int mid = (l + r) >> 1;
build(l, mid, x << 1);
build(mid + 1, r, x << 1 | 1);
t[x].mx = max(t[x << 1].mx, t[x << 1 | 1].mx);
t[x].mn = min(t[x << 1].mn, t[x << 1 | 1].mn);
t[x].gcd = __gcd(t[x << 1].gcd, t[x << 1 | 1].gcd);
}
void update_1(int l, int r, int x, int p, int d) {
if(l == r) {
t[x].mx = t[x].mn = d;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) {
update_1(l, mid, x << 1, p, d);
} else {
update_1(mid + 1, r, x << 1 | 1, p, d);
}
t[x].mx = max(t[x << 1].mx, t[x << 1 | 1].mx);
t[x].mn = min(t[x << 1].mn, t[x << 1 | 1].mn);
}
void update_2(int l, int r, int x, int p, int d) {
if(l == r) {
t[x].gcd = abs(d);
return;
}
int mid = (l + r) >> 1;
if(p <= mid) {
update_2(l, mid, x << 1, p, d);
} else {
update_2(mid + 1, r, x << 1 | 1, p, d);
}
t[x].gcd = __gcd(t[x << 1].gcd, t[x << 1 | 1].gcd);
}
void update_3(int l, int r, int x, int p, int d) {
if(l == r) {
t[x].pre = d;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) {
update_3(l, mid, x << 1, p, d);
} else {
update_3(mid + 1, r, x << 1 | 1, p, d);
}
t[x].pre = max(t[x << 1].pre, t[x << 1 | 1].pre);
}
int query_mx(int l, int r, int x, int a, int b) {
if(l > b || r < a) {
return 0;
}
if(l >= a && r <= b) {
return t[x].mx;
}
int mid = (l + r) >> 1;
return max(query_mx(l, mid, x << 1, a, b), query_mx(mid + 1, r, x << 1 | 1, a, b));
}
int query_mn(int l, int r, int x, int a, int b) {
if(l > b || r < a) {
return 1e9 + 1;
}
if(l >= a && r <= b) {
return t[x].mn;
}
int mid = (l + r) >> 1;
return min(query_mn(l, mid, x << 1, a, b), query_mn(mid + 1, r, x << 1 | 1, a, b));
}
int query_gcd(int l, int r, int x, int a, int b) {
if(l > b || r < a) {
return 0;
}
if(l >= a && r <= b) {
return t[x].gcd;
}
int mid = (l + r) >> 1;
return __gcd(query_gcd(l, mid, x << 1, a, b), query_gcd(mid + 1, r, x << 1 | 1, a, b));
}
int query_pre(int l, int r, int x, int a, int b) {
if(l > b || r < a) {
return 0;
}
if(l >= a && r <= b) {
return t[x].pre;
}
int mid = (l + r) >> 1;
return max(query_pre(l, mid, x << 1, a, b), query_pre(mid + 1, r, x << 1 | 1, a, b));
}
int main() {
n = read();
m = read();
for(int i = 1; i <= n; ++i) {
a[i] = read();
if(mp.find(a[i]) == mp.end()) {
mp[a[i]] = ++id;
s[id].insert(0);
}
}
build(1, n, 1);
for(int i = 1; i <= n; ++i) {
update_3(1, n, 1, i, *(--s[mp[a[i]]].end()));
s[mp[a[i]]].insert(i);
}
while(m--) {
int opt = read(), l, r, p, x, y, k, mx, mn, t;
if(opt == 1) {
x = read() ^ last;
y = read() ^ last;
p = mp[a[x]];
s[p].erase(x);
set<int> :: iterator it = s[p].lower_bound(x);
if(it != s[p].end()) {
t = *it;
update_3(1, n, 1, t, *(--it));
}
if(mp.find(y) == mp.end()) {
mp[y] = ++id;
s[id].insert(0);
}
p = mp[y];
it = s[p].lower_bound(x);
if(it != s[p].end()) {
update_3(1, n, 1, *it, x);
}
update_3(1, n, 1, x, *(--it));
s[p].insert(x);
a[x] = y;
update_1(1, n, 1, x, y);
update_2(1, n, 1, x, y - a[x - 1]);
if(x + 1 <= n) {
update_2(1, n, 1, x + 1, a[x + 1] - y);
}
} else {
l = read() ^ last;
r = read() ^ last;
k = read() ^ last;
if(l > r) {
swap(l, r);
}
mx = query_mx(1, n, 1, l, r);
mn = query_mn(1, n, 1, l, r);
if(l == r) {
++last;
puts("Yes");
} else if(k == 0) {
if(mn == mx) {
++last;
puts("Yes");
} else {
puts("No");
}
} else if(mx - mn == (long long)(r - l) * k && query_gcd(1, n, 1, l + 1, r) % k == 0 && query_pre(1, n, 1, l, r) < l) {
++last;
puts("Yes");
} else {
puts("No");
}
}
}
return 0;
}