RT,用树状数组和线段树各写了一遍,全是10分,我不能理解/yiw。
#include<bits/stdc++.h>
#define int long long
#define pb push_back
namespace IO {
#define int long long
#define gh getchar
inline int read(){char ch=gh();int x=0;bool t=0;while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}
inline char getc(){char ch=gh();while(ch<'a'||ch>'z') ch=gh();return ch;}
inline void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9){write(x / 10);}putchar((x % 10 + '0'));}
}
using namespace IO;
using namespace std;
const int Maxn = 300010;
int a[Maxn];
int n, m;
#define lowbit(x) x & (-x)
struct SumBit{
int c[Maxn << 2];
void Update(int i,int k){
while(i <= n){
c[i] += k;
i += lowbit(i);
}
}
int Sum(int i){
int res = 0;
while(i > 0){
res += c[i];
i -= lowbit(i);
}
return res;
}
}t1;
struct MaxSegmentTree{
int Tree[Maxn << 2], ma[Maxn << 2];
#define ls(p) p << 1
#define rs(p) p << 1 | 1
void push_up(int p){
ma[p] = max(ma[ls(p)], ma[rs(p)]);
}
int build(int l, int r, int p){
if(l == r){
return ma[p] = a[l];
}
int mid = (l + r) >> 1;
return ma[p] = max(build(l, mid, ls(p)), build(mid + 1, r, rs(p)));
}
void update(int l, int r, int p, int u, int val){
if(l == r) {ma[p] = val; return;}
int mid = (l + r) >> 1;
if(u <= mid) update(l, mid, ls(p), u, val);
else update(mid + 1, r, rs(p), u, val);
push_up(p);
}
int query(int l, int r, int L, int R, int p){ // l,r 为查询
if(L <= l && r <= R){
return ma[p];
}
if(l > R || r < l) return 0;
int mid = (l + r) >> 1;
return max(query(l,mid,L,R,ls(p)), query(mid+1,r,L,R,rs(p)));
}
}t2;
struct MinSegmentTree{
int Tree[Maxn << 2], mi[Maxn << 2];
#define ls(p) p << 1
#define rs(p) p << 1 | 1
void push_up(int p){
mi[p] = min(mi[ls(p)], mi[rs(p)]);
}
int build(int l, int r, int p){
if(l == r){
return mi[p] = a[l];
}
int mid = (l + r) >> 1;
return mi[p] = min(build(l, mid, ls(p)), build(mid + 1, r, rs(p)));
}
void update(int l, int r, int p, int u, int val){
if(l == r) {mi[p] = val; return;}
int mid = (l + r) >> 1;
if(u <= mid) update(l, mid, ls(p), u, val);
else update(mid + 1, r, rs(p), u, val);
push_up(p);
}
int query(int l, int r, int L, int R, int p){ // l,r 为查询
if(L <= l && r <= R){
return mi[p];
}
if(l > R || r < l) return 0;
int mid = (l + r) >> 1;
return min(query(l,mid,L,R,ls(p)), query(mid+1,r,L,R,rs(p)));
}
}t3;
struct MaxBIT{
int h[Maxn << 1];
void update(int x){
while(x <= n){
h[x] = a[x];
for(int i = 1; i < lowbit(x); i <<= 1)
h[x]=max(h[x],h[x-i]);
x += lowbit(x);
}
return ;
}
int query(int x, int y){
int ans = 0;
while (y >= x){
ans = max(a[y], ans);
y--;
for (; y-lowbit(y) >= x; y -= lowbit(y))
ans = max(h[y], ans);
}
return ans;
}
}t4;
struct MinBIT{
int h[Maxn << 1];
void update(int x){
while(x <= n){
h[x] = a[x];
for(int i = 1; i < lowbit(x); i <<= 1)
h[x]=min(h[x],h[x-i]);
x += lowbit(x);
}
return ;
}
int query(int x, int y){
int ans = 114514111;
while (y >= x){
ans = min(a[y], ans);
y--;
for (; y-lowbit(y) >= x; y -= lowbit(y))
ans = min(h[y], ans);
}
return ans;
}
}t5;
signed main(){
// freopen("P5278_1.in","r",stdin);
// freopen("kk.out","w",stdout);
int lst = 0;
int m;
cin >> n >> m;
for(int i = 1; i <= n; i++){
cin >> a[i];
t1.Update(i,a[i]);
t4.update(i);
t5.update(i);
}
for(int i = 1; i <= m; i++){
int op;
cin >> op;
if(op == 1){
int x, y;
cin >> x >> y;
x ^= lst, y ^= lst;
int p = a[x];
a[x] = y;
t1.Update(x,y-p);
// t2.update(1,n,1,x,y);
// t3.update(1,n,1,x,y);
t4.update(x);
t5.update(x);
}
else{
int l, r, k;
cin >> l >> r >> k;
l ^= lst, r ^= lst, k ^= lst;
int sum = t1.Sum(r) - t1.Sum(l-1);
// int max = t2.query(l,r,1,n,1);
// int min = t3.query(l,r,1,n,1);
int max = t4.query(l,r);
int min = t5.query(l,r);
// cout << sum << " " << max << " " << min << endl;
if(max - min == k * (r - l) && sum == (max + min) * (r - l + 1) / 2 ) {
cout << "Yes\n";
lst++;
}
else cout << "No\n";
}
}
}