Description
有一个字符串组成的集合,初始为空集,有qq个操作,操作分两种:
在集合中加入字符串ss,长度为偶数
2 a b c d:2 a b c d:问集合中有多少字符串可以被表示成a+s1+b+c+s2+da+s1+b+c+s2+d的形式且|a|+|s1|+|b|=|c|+|s2|+|d||a|+|s1|+|b|=|c|+|s2|+|d|,其中s1,s2s1,s2为任意字符串,也可以是空串
Input
第一行一整数TT表示用例组数,每组用例首先输入一整数表示操作数,之后qq行每行输入一个操作
Output
对于每个查询操作输出结果
Sample Input
1
10
1 abcqaq
1 abcabcqaqqaq
2 ab bc qa aq
2 a c q q
1 abcabcqaqqwq
2 ab bc qa aq
2 a c q q
1 abcq
2 a c q q
2 a b c q
Sample Output
1
2
1
3
3
1
Solution
把集合中每个字符串分成长度相同的两部分,把这两部分字符串的前缀和后缀都hashhash后存起来,对于输入的a,b,c,da,b,c,d,只要该字符串的前半部分的前缀后缀hashhash值分别与a,ba,b的hashhash值相同,后半部分的前缀后缀hashhash值分别与c,dc,d的hashhash值相同则该字符串满足条件
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=30005,maxm=2000005;
#define mod 1000000007
vector<int>al[maxn],ar[maxn],bl[maxn],br[maxn];
int T,q,len[maxn],res;
char s[maxm],a[maxm],b[maxm],c[maxm],d[maxm];
int lhash(char *s,int n)
{
int ans=0;
for(int i=0;i<n;i++)ans=(26ll*ans+s[i]-'a')%mod;
return ans;
}
int rhash(char *s,int n)
{
int ans=0;
for(int i=n-1;i>=0;i--)ans=(26ll*ans+s[i]-'a')%mod;
return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
for(int i=0;i<res;i++)al[i].clear(),ar[i].clear(),bl[i].clear(),br[i].clear();
res=0;
scanf("%d",&q);
while(q--)
{
int op;
scanf("%d",&op);
if(op==1)
{
scanf("%s",s);
int n=strlen(s),temp=0;
for(int i=0;i<n/2;i++)
{
temp=(26ll*temp+s[i]-'a')%mod;
al[res].push_back(temp);
}
temp=0;
for(int i=n/2-1;i>0;i--)
{
temp=(26ll*temp+s[i]-'a')%mod;
ar[res].push_back(temp);
}
temp=0;
for(int i=n/2;i<n;i++)
{
temp=(26ll*temp+s[i]-'a')%mod;
bl[res].push_back(temp);
}
temp=0;
for(int i=n-1;i>=n/2;i--)
{
temp=(26ll*temp+s[i]-'a')%mod;
br[res].push_back(temp);
}
len[res]=n/2;
res++;
}
else
{
scanf("%s%s%s%s",a,b,c,d);
int la=strlen(a),lb=strlen(b),lc=strlen(c),ld=strlen(d);
int ans=0;
for(int i=0;i<res;i++)
{
if(la+lb>len[i]||lc+ld>len[i])continue;
if(lhash(a,la)==al[i][la-1]&&rhash(b,lb)==ar[i][lb-1]&&lhash(c,lc)==bl[i][lc-1]&&rhash(d,ld)==br[i][ld-1])ans++;
}
printf("%d\n",ans);
}
}
}
return 0;
}