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;  
}

  

posted @ 2020-07-27 08:06  EM-LGH  阅读(259)  评论(0编辑  收藏  举报