Vasya has recently learned at school what a number's divisor is and decided to determine a string's divisor. Here is what he came up with.
String a is the divisor of string b if and only if there exists a positive integer x such that if we write out string a consecutively x times, we get string b. For example, string "abab" has two divisors — "ab" and "abab".
Now Vasya wants to write a program that calculates the number of common divisors of two strings. Please help him.
Input
The first input line contains a non-empty string s1.
The second input line contains a non-empty string s2.
Lengths of strings s1 and s2 are positive and do not exceed 105. The strings only consist of lowercase Latin letters.
Output
Print the number of common divisors of strings s1 and s2.
Examples
input
abcdabcd abcdabcdabcdabcd
output
2
input
aaa aa
output
1
Note
In first sample the common divisors are strings "abcd" and "abcdabcd".
In the second sample the common divisor is a single string "a". String "aa" isn't included in the answer as it isn't a divisor of string "aaa".
题意: 给出两字符串,询问两串有多少个公共循环部分。例如串abababab中,ab、abab、abababab都是循环部分。
分析: 首先考虑一个字符串的循环部分一定是由一个或多个最小循环部分连接而成。还是在串abababab中,ab是最小循环部分,abab和abababab是循环部分,显然循环部分都是由最小循环部分组成的。因此可以求出两串的最小循环部分,如果最小循环部分都不同那么两串一定不具有公共的循环部分。当两串最小循环部分相同时,记录下最小循环部分分别在两串中出现次数t1、t2。由于t1、t2的每个因子都分别代表一个循环部分,因此最终答案即为t1、t2公因子个数。还有些小细节详见代码。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
char s1[100005], s2[100005];
int _next1[100005], _next2[100005];
signed main()
{
scanf("%s%s", s1+1, s2+1);
int len1 = strlen(s1+1), len2 = strlen(s2+1);
for(int i = 2, j = 0; i <= len1; i++)
{
while(j && s1[j+1] != s1[i])
j = _next1[j];
if(s1[j+1] == s1[i])
j++;
_next1[i] = j;
}
for(int i = 2, j = 0; i <= len2; i++)
{
while(j && s2[j+1] != s2[i])
j = _next2[j];
if(s2[j+1] == s2[i])
j++;
_next2[i] = j;
}
int t1 = len1-_next1[len1], t2 = len2-_next2[len2];//最小循环部分长度
if(len1 % t1 != 0)//可能会出现ab|ab|a这样的串,需要进一步修正
t1 = len1;
if(len2 % t2 != 0)
t2 = len2;
s1[t1+1] = '\0', s2[t2+1] = '\0';
int ans = 0;
if(strcmp(s1+1, s2+1) == 0)//如果最小循环部分相同,则统计答案,否则答案直接为0
{
int up = max(len1, len2)/t1, down = min(len1, len2)/t1;//最小循环部分出现次数
for(int i = 1; i <= down; i++)
{
if(up % i == 0 && down % i == 0)
ans++;
}
cout << ans;
}
else
puts("0");
return 0;
}