hdu3973 线段树+RK

来源:互联网 发布:英文聊天翻译软件 编辑:程序博客网 时间:2024/04/29 12:40

题意:给出n个模式串和一个母串   然后修改操作是修改母串中的某一个字母  询问操作是给出一堆的区间 然后问这个区间是否满足n个模式串中的一个 

解法:修改的话就是线段树的单点修改  关键在于O(1)判断字符串 那么我们采用字符串hash就可以了 

把字符串看成一个素数进制的数 然后预处理每一位的位权 我们就可以把n个模式串全部保存在map里面 然后就可以判断是否存在了 

对于线段数,当然是储存每一个区间的hash值了 

当然这一题应该还有更好的做法 就是纯字符串的判断 这个先学习下

#include<map>#include<cstdio>#include<string.h>#include<algorithm>using namespace std;#define ll long long#define maxn 222222#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)#define mul 27map<ll,int>mp;char ss[maxn*2];ll ha[maxn<<2],p[maxn];int scan(){    int res=0,ch;    while(!((ch= getchar())>='0'&&ch<='9')){        if(ch==EOF)return 1<<30;    }    res=ch-'0';    while((ch=getchar())>='0'&&ch<='9')        res=res*10+(ch-'0');    return res;}void val(){    int len=(int)strlen(ss); ll ans=0;    for(int i=0;i<len;++i)ans+=(ss[i]-'a'+1)*p[len-i-1];    mp[ans]=1;}int n,m,a,b;char op[111];void up(int rt,int l,int r){ha[rt]=ha[ls]*p[r-mid]+ha[rs];}void build(int rt,int l,int r){    if(l==r){ha[rt]=ss[l]-'a'+1;return ;}    build(ls,l,mid);    build(rs,mid+1,r);    up(rt,l,r);}void ins(int rt,int l,int r,int pos,char x){    if(l==r){ha[rt]=x-'a'+1;return ;}    if(pos<=mid)ins(ls,l,mid,pos,x);    if(mid<pos)ins(rs,mid+1,r,pos,x);    up(rt,l,r);}ll query(int rt,int l,int r,int L,int R){    if(L<=l&&r<=R)return ha[rt];    if(R<=mid)return query(ls,l,mid,L,R);    else if(mid<L)return query(rs,mid+1,r,L,R);    else{        ll ansl=query(ls,l,mid,L,mid),ansr=query(rs,mid+1,r,mid+1,R);        return ansl*(p[R-mid])+ansr;    }}int main(){    int _;_=scan();    ll ans=1;    for(int i=0;i<200005;++i)p[i]=ans,ans*=mul;    for(int z=1;z<=_;++z){        mp.clear();        scanf("%d",&n);        while(n--)scanf("%s",ss),val();                scanf("%s%d",ss+1,&m);n=(int)strlen(ss+1);                build(1,1,n);printf("Case #%d:\n",z);        while(m--){            scanf("%s",op);            if(*op=='Q'){                a=scan(),b=scan();++a,++b;                ll ans=query(1,1,n,a,b);                if(mp[ans])printf("Yes\n");                else printf("No\n");            }else if(*op=='C'){                a=scan();                scanf("%s",op);++a;                ins(1,1,n,a,op[0]);            }        }    }    return 0;}


0 0
原创粉丝点击