伪 Hash 做法,一直过不去第3,4个点
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
#define ls x<<1
#define rs x<<1|1
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e6+10,INF=1e9;
const ull base=168717137ull;
int n,m,s[N];
ull p[N];
struct Segment_Tree
{
ull has;
int mn;
}tre[N<<2];
struct Node
{
int mn;
ull has;
Node friend operator + (Node x,Node y)
{
return (Node){min(x.mn,y.mn),x.has+y.has};
}
};
void push_up(int x)
{
tre[x].has=tre[ls].has+tre[rs].has;
tre[x].mn=min(tre[ls].mn,tre[rs].mn);
}
void insert(int x,int l,int r,int pos,int num)
{
if(l==r)
{
tre[x].has=p[num];
tre[x].mn=num;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) insert(ls,l,mid,pos,num);
else insert(rs,mid+1,r,pos,num);
push_up(x);
}
void build(int x,int l,int r)
{
if(l==r)
{
tre[x].has=p[s[l]];
tre[x].mn=s[l];
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(x);
}
Node query(int x,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return (Node){tre[x].mn,tre[x].has};
int mid=(l+r)>>1;
Node ans1=(Node){INF,0},ans2=(Node){INF,0};
if(L<=mid) ans1=query(ls,l,mid,L,R);
if(R>mid) ans2=query(rs,mid+1,r,L,R);
return ans1+ans2;
}
signed main()
{
n=read();
m=read();
p[0]=1;
for(int i=1;i<N;i++)
p[i]=p[i-1]*base;
for(int i=1;i<=n;i++)
s[i]=read();
build(1,1,n);
for(int i=1,opt,x,y,l1,r1,l2,r2;i<=m;i++)
{
opt=read();
if(!opt)
{
x=read();y=read();
insert(1,1,n,x,y);
continue;
}
l1=read();r1=read();l2=read();r2=read();
Node ans1=query(1,1,n,l1,r1);
Node ans2=query(1,1,n,l2,r2);
if(ans1.mn<ans2.mn) swap(ans1,ans2);
if(p[ans1.mn-ans2.mn]*ans2.has==ans1.has) printf("YES\n");
else printf("NO\n");
}
return 0;
}