永不言弃 题解(线段树维护hash+二分)

题目链接

题目思路

如题目所示,就是二分求第一个不同的点,然后判断后面的字符串是否相同即可

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const ll INF=0x3f3f3f3f3f3f3f3f;
ull tree[maxn<<2],base=233;
ull pre[maxn];
int n,m;
char s[maxn];
void pushup(int node,int l,int r){
    int mid=(l+r)/2;
    // [mid+1,r]
    tree[node]=tree[node<<1]*pre[r-mid]+tree[node<<1|1];
}
void build(int node,int l,int r){
    if(l==r){
        tree[node]=s[l];
        return ;
    }
    int mid=(l+r)/2;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
    pushup(node,l,r);
}
void update(int node,int pos,int val,int l,int r){
    if(l==r){
        tree[node]=val;
        return ;
    }
    int mid=(l+r)/2;
    if(mid>=pos) update(node<<1,pos,val,l,mid);
    else update(node<<1|1,pos,val,mid+1,r);
    pushup(node,l,r);
}
ull query(int node,int L,int R,int l,int r){
    if(L<=l&&r<=R){
        return tree[node];
    }
    int mid=(l+r)/2;
    ull ans=0;
    if(mid>=L) ans+= pre[max(0,min(R , r)- mid)]*query(node<<1,L,R,l,mid);
    if(mid<R) ans+=query(node<<1|1,L,R,mid+1,r);
    return ans;
}
int main(){
    pre[0]=1;
    for(int i=1;i<=1e5;i++){
        pre[i]=pre[i-1]*base;
    }
    scanf("%d%d %s",&n,&m,s+1);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt,x,l1,r1,l2,r2,flag;
        char y;
        scanf("%d",&opt);
        if(opt==1){
            scanf("%d %c",&x,&y);
            update(1,x,y,1,n);
        }else{
            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
            if(r1-l1!=r2-l2){
                flag=0;
            }else{
                int len=r1-l1+1;
                int l=1,r=len,ans=0;
                while(l<=r){
                    int mid=(l+r)/2;
                    ull temp1=query(1,l1,l1+mid-1,1,n);
                    ull temp2=query(1,l2,l2+mid-1,1,n);
                    if(temp1==temp2){
                        ans=mid;
                        l=mid+1;
                    }else{
                        r=mid-1;
                    }
                }
                if(ans==len||ans==len-1){
                    flag=1;
                }else{
                    ull temp1=query(1,l1+ans+1,r1,1,n);
                    ull temp2=query(1,l2+ans+1,r2,1,n);
                    flag=(temp1==temp2);
                }
            }
            printf(flag?"YES\n":"NO\n");
        }
    }
    return 0;
}
posted @ 2021-07-16 22:17  hunxuewangzi  阅读(42)  评论(0编辑  收藏  举报