AC's String
Time Limit: 30000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1266 Accepted Submission(s): 352
For example, S = "abcd", and the given words {Wi} = {"bc", "ad", "dd"}. Then Only S[2..3] = "bc" exists in the given words. (In this problem, the first element of S has the index "0".)
However, this is toooooooooooo easy for acmers ! The stupid and evil AC will now change some letters in S. So could you solve this problem now?
Then for every case, there is one integer n in the first line indicates the number of the given words(The size of the {Wi}) . Then n lines has one string which only has 'a'- 'z'. (1 <= n <= 10000, sigma|Wi| <= 2000000) .
Then one line has one string S, here |S| <= 100000.
Then one integer m, indicating the number of operations. (1 <= m <= 100000)
Then m lines , each line is the operation:
(1)Q L R , tell AC whether the S[L..R] exists in the given strings ;
(2)C X Y , chang S[X] to Y, here Y : 'a'-'z' .
題解:字符串hash成一個數,線段樹維護hash值,n個字符串用map保存,查詢時判斷即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
#define lc idx<<1
#define rc idx<<1|1
#define lson l,mid,lc
#define rson mid+1,r,rc
using namespace std;
const int N = 100010;
const int o=31;
typedef long long ll;
ll p[N];
char s[N*20];
map<ll,bool>mp;
int n;
void init() {
p[0]=1;
for(int i=1; i<N; i++)p[i]=p[i-1]*o;
}
void Hash(char s[]) {
int len=strlen(s);
ll res=0;
for(int i=0; i<len; i++) {
res=res*o+s[i]-'a'+1;
}
mp[res]=true;
}
ll tree[N*4];
void push_up(int idx,int m) {
tree[idx]=tree[lc]*p[m]+tree[rc];
}
void build(int l,int r,int idx) {
if(l==r) {
tree[idx]=s[l]-'a'+1;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(idx,r-mid);
}
void update(int l,int r,int idx,int x,int v) {
if(l==r) {
tree[idx]=v;
return;
}
int mid=(l+r)>>1;
if(x<=mid)update(lson,x,v);
else update(rson,x,v);
push_up(idx,r-mid);
}
ll query(int l,int r,int idx,int x,int y) {
if(l>=x&&y>=r)
return tree[idx];
if(l<x&&r<x||(l>y&&r>y))return 0;
int mid=(l+r)>>1;
return query(rson,x,y)+query(lson,x,y)*p[max(min(y,r)-mid,0)];
}
int main() {
//freopen("test.in","r",stdin);
int t;
init();
cin>>t;
int ca=1;
while(t--) {
scanf("%d",&n);
mp.clear();
for(int i=0; i<n; i++) {
scanf("%s",s);
Hash(s);
}
scanf("%s",s+1);
n=strlen(s+1);
build(1,n,1);
int m;
scanf("%d",&m);
char c[2];
int l,r;
printf("Case #%d:\n",ca++);
while(m--) {
scanf("%s%d",c,&l);
if(c[0]=='Q') {
scanf("%d",&r);
ll res=query(1,n,1,++l,++r);
bool flag=1;
if(mp.find(res)==mp.end())flag=0;
printf("%s\n",flag?"Yes":"No");
continue;
}
scanf("%s",c);
update(1,n,1,++l,c[0]-'a'+1);
}
}
return 0;
}