LuoguP6688 可重集 线段树+hash
线段树加 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;
}

浙公网安备 33010602011771号