2019南京網絡賽 Substring

#include<bits/stdc++.h>
#define N 100010
#define INF 0x3f3f3f3f
#define eps 1e-6
#define pi 3.141592653589793
#define mod 1000000007
#define P 998244353
#define LL long long
#define pb push_back
#define fi first
#define se second
#define cl clear
#define si size
#define lb lower_bound
#define ub upper_bound
#define bug(x) cerr<<#x<<"      :   "<<x<<endl
#define mem(x,y) memset(x,0,sizeof(int)*(y))
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace __gnu_pbds;
gp_hash_table<LL,int>mp;

char s[N],t[N];
LL L[N],id[N];
int f[N];
LL p[N],pp[N];
int ans[N];
LL has[N];
bool cmp(int a,int b){
	return L[a]<L[b];
}

int main(){
	p[0]=pp[0]=1; for(int i=1;i<26;i++) p[i]=1ll*p[i-1]*1331%mod,pp[i]=1ll*pp[i-1]*1331%P;
	int T; sc(T);
	while(T--){
		mp.cl();
		scanf("%s",s+1);
		int len=strlen(s+1);		
		int n; sc(n);
		for(int i=1;i<=n;i++){
			scanf("%s",t+1);
			int len=strlen(t+1);
			int d[26]={0}; for(int i=2;i<len;i++) d[t[i]-'a']++;
			LL ha=0,ah=0; for(int i=0;i<26;i++) ha=(ha*1331+d[i])%mod,ah=(ah*1331+d[i])%P;
			ha=((ha*1331+t[1])%mod*1331+t[len])%mod;
			ah=((ah*1331+t[1])%P*1331+t[len])%P;
			mp[ha<<31|ah]=i;
			has[i]=ha<<31|ah;
			id[i]=i; L[i]=len;
		}
		sort(id+1,id+n+1,cmp);
		for(int i=1;i<=n;i++) ans[i]=f[i]=0;
		for(int i=1;i<=n;i++) if (!f[i]){
			for(int j=i+1;L[id[j]]==L[id[i]]&&j<=n;j++) f[j]=1;
			int x=L[id[i]];
			LL tmp=0,pmt=0;
			int d[26]={0}; for(int i=2;i<x;i++) d[s[i]-'a']++;
			for(int i=0;i<26;i++) tmp=(tmp*1331+d[i])%mod,pmt=(pmt*1331+d[i])%P;
			for(int i=1;i+x-1<=len;i++){
				LL ha=((tmp*1331+s[i])%mod*1331+s[i+x-1])%mod,
					ah=((pmt*1331+s[i])%P*1331+s[i+x-1])%P;

				if (mp.find(ha<<31|ah)!=mp.end()) ans[mp[ha<<31|ah]]++;
				tmp=(tmp-p[25-s[i+1]+'a']+p[25-s[i+x-1]+'a']+mod)%mod;
				pmt=(pmt-pp[25-s[i+1]+'a']+pp[25-s[i+x-1]+'a']+P)%P;
			}
		}
		for(int i=1;i<=n;i++) printf("%d\n",ans[mp[has[i]]]);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章