/*
3 3
1 2 7
1 1 2
1 3 2
2 1 3 0
*/
#include <bits/stdc++.h>
using namespace std;
#define srand srand(time(NULL))
#define random(x) rand() % (x)
#define il inline
#define ptc putchar
#define reg register
#define mp make_pair
typedef __int128 LL;
typedef long long ll;
typedef pair<int, int> PII;
namespace cyyh {
template <typename T>
il void read(T &x) {
x = 0; T f = 1; char ch;
while (!isdigit(ch = getchar())) f -= (ch == '-') << 1;
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch & 15), ch = getchar(); x *= f;
}
template <typename T>
il void write(T x) {
if (x < 0) ptc('-'), x = -x;
if (x > 9) write(x / 10);
ptc(x % 10 + '0');
}
template <typename T>
il T lowbit(const T &x) {
return x & -x;
}
}
using namespace cyyh;
const int N = 600001;
int n, m, pre[N], Val[N], a[N], dif[N];
map <int, int> idx;
set <int> st[N];
struct node {
int max; // 前驱最大值
int big, small; // 原数组最值
int gcd;
} tr[2][N << 2];
void pushup(int l, int r, int id) {
tr[0][id].max = max(tr[0][id << 1].max, tr[0][id << 1 | 1].max);
tr[1][id].big = max(tr[1][id << 1].big, tr[1][id << 1 | 1].big);
tr[1][id].small = min(tr[1][id << 1].small, tr[1][id << 1 | 1].small);
tr[1][id].gcd = __gcd(tr[1][id << 1].gcd, tr[1][id << 1 | 1].gcd);
}
int op, x, y, k;
void build(int l, int r, int id) {
if (l == r) {
tr[0][id].max = pre[l];
tr[1][id].big = a[l];
tr[1][id].small = a[l];
tr[1][id].gcd = abs(a[l] - a[l - 1]);
// else tr[1][id].gcd = k;
return ;
}
int mid = l + r >> 1;
build(l, mid, id << 1), build(mid + 1, r, id << 1 | 1);
pushup(l, r, id);
}
void modify(int l, int r, int x, int id, int k, int op) {
if (l > x || r < x) return ;
if (l == x && r == x) {
if (op == 0) tr[0][id].max = k;
else if (op == 3) {
tr[1][id].gcd = abs(a[l] - a[l - 1]);
// else tr[1][id].gcd = k;
// cout << tr[1][id].gcd << "!1" << endl;
}
else tr[1][id].big = tr[1][id].small = k;
return ;
}
int mid = l + r >> 1;
if (x <= mid) modify(l, mid, x, id << 1, k, op);
else modify(mid + 1, r, x, id << 1 | 1, k, op);
pushup(l, r, id);
}
int query(int l, int r, int x, int y, int id, int type) {
if (l > y || r < x) {
if (type == 1 || type == 0) return 0;
else if (type == 2) return INT_MAX;
else return k;
}
if (l >= x && r <= y) {
if (type == 0) return tr[0][id].max;
else if (type == 1) return tr[1][id].big;
else if (type == 2) return tr[1][id].small;
else if (type == 3) return tr[1][id].gcd;
}
int mid = l + r >> 1;
if (type == 0 || type == 1) return max(query(l, mid, x, y, id << 1, type), query(mid + 1, r, x, y, id << 1 | 1, type));
else if (type == 2) return min(query(l, mid, x, y, id << 1, type), query(mid + 1, r, x, y, id << 1 | 1, type));
else return __gcd(query(l, mid, x, y, id << 1, type), query(mid + 1, r, x, y, id << 1 | 1, type));
}
int tot = 0, cnt;
int main() {
// freopen("1.txt", "w", stdout);
read(n), read(m);
for (int i = 1; i <= n; ++i) {
read(a[i]);
int x = a[i];
if (!idx[x]) idx[x] = ++tot; // idx离散化
x = idx[x];
set <int> :: iterator last = st[x].end();
if (last != st[x].begin()) pre[i] = *(--last);
else pre[i] = 0;
st[x].insert(i); // st记录值为x的是哪些位置
Val[i] = x; // pos记录位置为i的是什么
}
for (int i = 1; i <= n; ++i) dif[i] = a[i] - a[i - 1];
build(1, n, 1);
int line = 0;
// cout << query(1, n, 2, n, 1, 3) << endl;
while (m--) {
read(op), read(x), read(y);
x ^= cnt, y ^= cnt;
if (op == 1) {
a[x] = y;
// 修改x的位置的值为y
// 改动3个元素
// 将x的pre改为前面最近的一个y
// 将后面一个y的pre改为x
// 将后面一个x的pre改为前面最近的一个x
modify(1, n, x, 1, y, 1);
modify(1, n, x, 1, y, 3);
if (x < n) modify(1, n, x + 1, 1, a[x + 1], 3);
if (!idx[y]) idx[y] = ++tot;
y = idx[y];
set <int> :: iterator it, it2;
int val = Val[x];
Val[x] = y;
it = st[val].lower_bound(x);
st[val].erase(x);
it = st[val].upper_bound(x);
it2 = st[val].lower_bound(x);
if (it != st[val].end() && it2 != st[val].begin()) --it2, modify(1, n, *it, 1, *it2, 0);
st[y].insert(x);
it = st[y].lower_bound(x);
if (it != st[y].begin()) --it, modify(1, n, x, 1, *it, 0);
else modify(1, n, x, 1, 0, 0);
it = st[y].upper_bound(x);
if (it != st[y].end()) modify(1, n, *it, 1, x, 0);
// cout << query(1, n, 2, 2, 1, 3) << endl;
} else {
++line;
read(k);
k ^= cnt;
// if (line == 199830) return cout << query(1, n, x, y, 1, 1) - query(1, n, x, y, 1, 2) << endl, 0;
if (x == y) {
puts("Yes");
++cnt;
continue;
}
// cout << query(1, n, 1, 3, 1, 0) << endl;
if (k == 0) {
if (query(1, n, x, y, 1, 1) - query(1, n, x, y, 1, 2) == 0) puts("Yes"), ++cnt;
else puts("No");
}
else {
if (query(1, n, x, y, 1, 0) < x && ((query(1, n, x, y, 1, 1) - query(1, n, x, y, 1, 2) == (y - x) * k)) && query(1, n, x + 1, y, 1, 3) == k) puts("Yes"), ++cnt;
else puts("No");
}
}
}
return 0;
}
不需要看我的代码(我知道很臭)
我只想知道如何过掉这个点,或有没有hack