线段树加 hash 判重模板题.
hash 的话必须要用双 base 哈希,否则会 WA.
然后这道题中最好不要用自然溢出,感觉比取模还要慢一些.
由于读入量巨大,必须要开读入优化才能过.
哈希的方式就是对于每个数维护 $\sum base^{num[i]}$,由于值域不大,提前预处理出来 base 的 num 次方即可.
code:
#include <bits/stdc++.h> #define N 1000007 #define lson now<<1 #define rson now<<1|1 #define mod 998244353 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; const int A=2333; const int B=233; int nA[N],nB[N]; int val[N]; void init() { nA[0]=nB[0]=1; for(int i=1;i<N;++i) { nA[i]=(ll)nA[i-1]*A%mod; nB[i]=(ll)nB[i-1]*B%mod; } } struct data { int ha,hb; int mi; data() {} data operator+(const data &b) const { data c; c.ha=(ll)(ha+b.ha)%mod; c.hb=(ll)(hb+b.hb)%mod; c.mi=min(mi,b.mi); return c; } }s[N<<2]; void build(int l,int r,int now) { if(l==r) { s[now].ha=nA[val[l]]; s[now].hb=nB[val[l]]; s[now].mi=val[l]; return; } int mid=(l+r)>>1; build(l,mid,lson),build(mid+1,r,rson); s[now]=s[lson]+s[rson]; } void update(int l,int r,int now,int p,int v) { if(l==r) { s[now].ha=nA[v]; s[now].hb=nB[v]; s[now].mi=v; return; } int mid=(l+r)>>1; if(p<=mid) { update(l,mid,lson,p,v); } else { update(mid+1,r,rson,p,v); } s[now]=s[lson]+s[rson]; } data query(int l,int r,int now,int L,int R) { if(l>=L&&r<=R) return s[now]; int mid=(l+r)>>1; if(L<=mid&&R>mid) { return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R); } else if(L<=mid) return query(l,mid,lson,L,R); else return query(mid+1,r,rson,L,R); } char *p1,*p2,buf[100000]; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() { int x=0; char c; do { c=nc(); } while(c<48); while(c>47) { x=(((x<<2)+x)<<1)+(c^48); c=nc(); } return x; } int main() { // setIO("input"); init(); int n,Q,x,y,z; n=rd(),Q=rd(); for(int i=1;i<=n;++i) val[i]=rd(); build(1,n,1); for(int i=1;i<=Q;++i) { int op; op=rd(); if(op==0) { x=rd(),y=rd(); update(1,n,1,x,y); } else { int L[3],R[3]; L[1]=rd(),R[1]=rd(),L[2]=rd(),R[2]=rd(); data a1=query(1,n,1,L[1],R[1]); data a2=query(1,n,1,L[2],R[2]); if(a1.mi>a2.mi) swap(a1,a2); int det=abs(a2.mi-a1.mi); a1.ha=(ll)a1.ha*nA[det]%mod; a1.hb=(ll)a1.hb*nB[det]%mod; if(a1.ha==a2.ha&&a1.hb==a2.hb) { printf("YES\n"); } else { printf("NO\n"); } } } return 0; }