题干:

Xenia is an amateur programmer. Today on the IT lesson she learned about the Hamming distance.

The Hamming distance between two strings s = s1s2... sn and t = t1t2... tn of equal length n is value . Record [si ≠ ti] is the Iverson notation and represents the following: if si ≠ ti, it is one, otherwise — zero.

Now Xenia wants to calculate the Hamming distance between two long strings a and b. The first string a is the concatenation of n copies of string x, that is, . The second string b is the concatenation of m copies of string y.

Help Xenia, calculate the required Hamming distance, given n, x, m, y.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 1012). The second line contains a non-empty string x. The third line contains a non-empty string y. Both strings consist of at most 106 lowercase English letters.

It is guaranteed that strings a and b that you obtain from the input have the same length.

Output

Print a single integer — the required Hamming distance.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Examples

Input

100 10
a
aaaaaaaaaa

Output

0

Input

1 1
abacaba
abzczzz

Output

4

Input

2 3
rzr
az

Output

5

Note

In the first test case string a is the same as string b and equals 100 letters a. As both strings are equal, the Hamming distance between them is zero.

In the second test case strings a and b differ in their 3-rd, 5-th, 6-th and 7-th characters. Thus, the Hamming distance equals 4.

In the third test case string a is rzrrzr and string b is azazaz. The strings differ in all characters apart for the second one, the Hamming distance between them equals 5.

题目大意:

给出一个n,m 然后给出两个串的循环节S和T(不一定等长), n代表第一个串有多少次循环,m代表第二个串有多少次循环,问两个串的Hamming distance是多少,这个距离是指对应位置的字符如果相等对结果的贡献就是0,否者就是1。(加长的两个字符串等长)

解题报告:

   这是一道关于汉明距离的题目。首先涨一波知识:

这题第一眼应该就跟数论gcd,lcm相关(因为循环节和循环次数嘛最后还等长),而且数据量就知道不可能让你暴力,肯定是有重复计算,我们需要算那个最小的然后扩大相应的倍数。

于是首先想到只要比较了两个串的lcm长度,再扩大相应倍数就可以,但是这样的数据量还是会TLE,想想也知道啊,如果len1和len2互质的话,复杂度O(len1*len2),最坏为10^12。

想办法优化:

     分析一下会发现,在上面的想法中,有一部分比较是没有必要的,比如:

                  S:  abacdcde                 T:  acdaed

    S的长度为8,T的长度为6,len1与len2的gcd = 2,lcm = 24。

    比较时                

       

    T开头的a并不是和S中的每一位都能进行比较的,也就是说,在一个循环结中,可以一次性将T中的每一位与其将会与S中所对应的位置的字符都比较一下,也就是预处理出来。也不难发现,T的第一个字符,总与s[1]+k*gcd比较,第二个字符,总与s[2]+k*gcd比较...以此类推。(假设从s[1]为第一个字符而不是s[0])

设g=gcd(len1,len2),设ans为S和T中对应位置相同的字符的数目,方法就是在i from 0 to gcd(len1,len2)-1 的循环中,将S分为g个小段,每段长度为len1/g,统计每次该小段上第i个字符出现的次数,然后将T中g个小段的第i个字符出现的次数加入到ans中。最后将ans扩大相应倍数,然后再用总的长度减去ans就是答案。

传送门

AC代码1:(这是一个网络的代码,但是因为dpa数组开成了longlong,所以MLE了,下面有一个优化版本)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int qq = 1e6+10;
char a[qq],b[qq];
int dpa[qq][27],dpb[qq][27];
ll gcd(ll a, ll b){
	return b==0?a:gcd(b, a%b);
}
ll lcm(ll a, ll b){
	return a/gcd(a, b)*b;
}
int main(){
	ll n,m;scanf("%lld%lld",&n,&m);
	scanf("%s%s",a,b);
	ll lena = strlen(a);
	ll lenb = strlen(b);
	ll g = gcd(lena, lenb);	 
	ll l = lena/g*lenb;
	memset(dpa, 0, sizeof(dpa));
	memset(dpb, 0, sizeof(dpb));
	for(int i=0; i<lena; ++i)	dpa[i%g][a[i]-'a']++;
	for(int i=0; i<lenb; ++i)	dpb[i%g][b[i]-'a']++;
	ll ans = 0;
	for(int i=0; i<g; ++i)
		for(int j=0; j<26; ++j)
			ans+=(ll)dpa[i][j]*dpb[i][j];
	ans = n*lena/l*ans;	//每一个长度为l的字符串中,所含相同的字符有ans个、 
						// 求长度为n*lena/l 个长度为l的字符串中,所含相同字符的总数、 
	ans = n*lena - ans;	//求反面、 然后用总长度减去相同字符的个数、 
	printf("%lld\n", ans);
	return 0;
}

AC代码2:(这样不需要二维数组,时间慢了一丢丢200+ms,但是剩下了很多空间复杂度)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e6 + 5;
char s1[MAX],s2[MAX];
ll cnt[50]; 
ll Gcd(ll a,ll b) {
	while(a^=b^=a^=b%=a);
	return b;
}

int main()
{
	ll n,m;
	cin>>n>>m;
	cin>>s1>>s2;
	ll len1 = strlen(s1);
	ll len2 = strlen(s2);
	ll gcd = Gcd(len1,len2);
	ll lcm = len1 * (len2 / gcd);
	
	ll l1=len1/gcd,l2=len2/gcd;
	ll ans = 0;
	for(ll i = 0; i<gcd; i++) {
		memset(cnt,0,sizeof cnt);
		for(ll j = 0; j<l1; j++) {
			cnt[s1[gcd*j + i]-'a'] ++;
		}
		for(ll j = 0; j<l2; j++) {
			ans += cnt[s2[gcd*j+i]-'a'];
		}
	}
	ans *=len1*n/ lcm ;
//	ans *= (m*gcd)/len1;
	ans = len1*n-ans;
	printf("%lld\n",ans);
	return 0 ;
 } 

总结:

   这题用的思维主要是:

                  1.求问题的反面。

                  2.cnt数组运用了桶计数的思想。空间换时间,1e6正好也开的下(对这个数字还是不太敏感啊你、、)(不对这题好像不是那个桶计数,,,这题cnt数组就开27 就够了)