时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
白兔有一个字符串T。白云有若干个字符串S1,S2..Sn。
白兔想知道,对于白云的每一个字符串,它有多少个子串是和T循环同构的。
提示:对于一个字符串a,每次把a的第一个字符移动到最后一个,如果操作若干次后能够得到字符串b,则a和b循环同构。
所有字符都是小写英文字母
输入描述:
第一行一个字符串T(|T|<=10^6)
第二行一个正整数n (n<=1000)
接下来n行为S1~Sn (|S1|+|S2|+…+|Sn|<=10^7),max(|S1|,|S2|,|S3|,|S4|,..|Sn|)<=10^6
输出描述:
输出n行表示每个串的答案
示例1
输入
abab
2
abababab
ababcbaba
输出
5
2
判断是否与主串循环同构,直接在主串后加上一段相同的,如abcde->abcdeabcde
用power[i]表示Base^i,这时的哈希函数与POJ3461 && LOJ#10033 Oulipo(字符串HASH)类似
令Hash[i]表示字符串的哈希值,则字符串的哈希值为
以10进制数字为例,123456,Hash[1]=1,Hash[2]=12,Hash[3]=123,Hash[4]=1234,Hash[5]=12345,Hash[6]=123456,
3456(l=3,r=6)=Hash[6]-Hash[2]*power[6-2+1]=123456-12*10000=3456。
AC代码:
//CSDN博客:https://blog.csdn.net/qq_40889820
#include<iostream>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<string>
#include<cstring>
#include<iomanip>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define mem(a,b) memset(a,b,sizeof(a))
#define random(a,b) (rand()%(b-a+1)+a)
#define ull unsigned long long
#define e 2.71828182
#define Pi 3.141592654
using namespace std;
const int MAXN=2e6+10;
const int Base=1e7+7;
const int mod=14937;
ull power[MAXN],htmp;
char T[MAXN],S[MAXN];
int lenT,lenS;
ull has[MAXN];
vector<ull> HashTable[mod];//邻接表
int n;
void add_edge(ull h)
{
int pos=h%mod;
HashTable[pos].push_back(h);
}
int find(ull h)
{
int pos=h%mod;
for(int i=0;i<HashTable[pos].size();++i)
{
if(HashTable[pos][i]==h) return 1;
}
return 0;
}
inline void initial_hash()
{
power[0]=1;
for(int i=1;i<=lenT;++i) power[i]=power[i-1]*Base;
for(int i=1;i<=lenT+lenT;++i)
{
has[i]=has[i-1]*Base+T[i];
if(i>=lenT)
{
T[i+1]=T[i-lenT+1];
htmp=has[i]-has[i-lenT]*power[lenT];
add_edge(htmp);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>(T+1);
lenT=strlen(T+1);
initial_hash();
cin>>n;
while(n--)
{
cin>>(S+1);
lenS=strlen(S+1);
int ans=0;
for(int i=1;i<=lenS;++i)
{
has[i]=has[i-1]*Base+S[i];
if(i>=lenT)
{
htmp=has[i]-has[i-lenT]*power[lenT];
ans+=find(htmp);
}
}
cout<<ans<<endl;
}
return 0;
}