设为首页 加入收藏

TOP

HDU 3973 AC's String
2015-11-21 01:05:38 来源: 作者: 【 】 浏览:3
Tags:HDU 3973 AC' String

本题使用字符串的Hash来解决。将一个字符串看成是一个P进制的数字,那么可以知道每一个字符串都可以被唯一表示(P> 256, 并不考虑高精度)。可是由于字符串的长度比较大,那么我们无法保存如此大的数字。于是使用Hash mod2^64来作为Hash.(的却可能会冲突,可是冲突的概率趋于无穷小)
然后就是Hash(s,P) = s[0]*P^(Len-1) + s[1] *P^(Len -2) + … + s[Len-1]*P^0 (mod2^64)
P随便选个素数什么的都可以。
之后假设没有修改操作,那么我们可以与处理出H[i]表示S[0..i]的Hash
那么为了获得S[l..r]的Hash,我们有:
S[0..r]= s[0]*P^r + s[1]*P^(r-1) +…+s[r]*P^0
S[0..l-1]=s[0]*P^(l-1)+s[1]*P^(l-2)+…+s[l-1]*P^0
于是
S[l..r]=s[l]*P^(r-l)+s[l+1]*P^(r-l-1)+…+s[r]*P^0
=S[0..r] – S[0..l-1]*P^(r-l+1)
=H[r] – H[l-1]*P^(r-l+1)
其中P^(r-l+1)显然直接预处理。
于是查询就可以O(1)
现在需要修改某些字符!
于是可以使用一颗线段树来维护
[L..R]维护S[L..R]的Hash,这样更新查询均解决。更新和查询均为O(logN)级别

[cpp]?
#include?
#include?
#include?
#define maxn 100010?
#define p 33?
using namespace std;?
typedef unsigned long long ll;?
struct Tree{?
??? int l,r;?
??? ll hashes;?
}tree[300000];?
char str[2000100];?
ll hh[maxn];?
void init(){?
??? int i;?
??? hh[0]=1;?
??? for(i=1;i<=maxn;i++)?
??????? hh[i]=hh[i-1]*p;?
}?
ll calhash(){?
??? int i,len=strlen(str);?
??? ll sum=0;?
??? for(i=0;i ??????? sum=sum*p+str[i]-'a'+1;?
??? return sum;?
}?
void build(int s,int t,int id){?
??? tree[id].l=s;tree[id].r=t;?
??? if(s==t){?
??????? tree[id].hashes=str[s]-'a'+1;?
??????? return;?
??? }?
??? int mid=(s+t)>>1;?
??? build(s,mid,id<<1);?
??? build(mid+1,t,id<<1|1);?
??? tree[id].hashes=tree[id<<1].hashes*hh[t-mid]+tree[id<<1|1].hashes;?
}?
void update(int l,int id){?
??? if(tree[id].l==tree[id].r){?
??????? tree[id].hashes=str[l]-'a'+1;?
??????? return ;?
??? }?
??? int mid=(tree[id].l+tree[id].r)>>1;?
??? if(l<=mid) update(l,id<<1);?
??? else update(l,id<<1|1);?
??? tree[id].hashes=tree[id<<1].hashes*hh[tree[id].r-mid]+tree[id<<1|1].hashes;?
}?
ll query(int s,int t,int id){?
??? if(tree[id].l==s && tree[id].r==t)?
??????? return tree[id].hashes;?
??? int mid=(tree[id].l+tree[id].r)>>1;?
??? if(t<=mid) return query(s,t,id<<1);?
??? else if(s>mid) return query(s,t,id<<1|1);?
??? return query(s,mid,id<<1)*hh[t-mid]+query(mid+1,t,id<<1|1);?
}?
int main(){?
??? int t,T,pos,l,r,i,q,n;?
??? char s1[10],s2[10];?
??? mapmp;?
??? init();?
??? scanf("%d",&T);?
??? for(t=1;t<=T;t++){?
??????? printf("Case #%d:\n",t);?
??????? scanf("%d",&n);?
??????? mp.clear();?
??????? for(i=1;i<=n;i++){?
??????????? scanf("%s",str);?
??????????? mp.insert(make_pair(calhash(),1));?
??????? }?
??????? scanf("%s",str);?
??????? int len=strlen(str);?
??????? build(0,len-1,1);?
??????? scanf("%d",&q);?
??????? for(i=1;i<=q;i++){?
??????????? scanf("%s",s1);?
??????????? if(s1[0]=='C'){?
??????????????? scanf("%d%s",&pos,s2);?
??????????????? str[pos]=s2[0];?
??????????????? update(pos,1);?
??????????? }?
??????????? else{?
??????????????? scanf("%d %d",&l,&r);?
??????????????? if(mp.find(query(l,r,1))!=mp.end()) printf("Yes\n");?
??????????????? else printf("No\n");?
??????????? }?
??????? }?
??? }?
}?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Poj 2411 Mondriaan's Dream .. 下一篇Fukuoka 2011 F - City Merger &l..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: