Codeforces1056E.Check Transcription(列舉+Hash)
阿新 • • 發佈:2018-12-01
題目連結:傳送門
題目:
E. Check Transcription time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output One of Arkady's friends works at a huge radio telescope. A few decades ago the telescope has sent a signal s towards a faraway galaxy. Recently theyView Code've received a response t which they believe to be a response from aliens! The scientists now want to check if the signal t is similar to s The original signal s was a sequence of zeros and ones (everyone knows that binary code is the universe-wide language). The returned signal t, however, does not look aseasy as s, but the scientists don't give up! They represented t as a sequence of English letters and say that t is similar to s if you can replace all zeros in s with some string r0 and all ones in s with some other string r1 and obtain t. The strings r0 and r1 must be different and non-empty. Please help Arkady's friend and find the number of possible replacements for zeros and ones (the number of pairs of strings r0 and r1) that transform s to t . Input The first line contains a string s (2≤|s|≤105) consisting of zeros and ones — the original signal. The second line contains a string t (1≤|t|≤106 ) consisting of lowercase English letters only — the received signal. It is guaranteed, that the string s contains at least one '0' and at least one '1'. Output Print a single integer — the number of pairs of strings r0 and r1 that transform s to t . In case there are no such pairs, print 0 . Examples Input Copy 01 aaaaaa Output Copy 4 Input Copy 001 kokokokotlin Output Copy 2 Note In the first example, the possible pairs (r0,r1) are as follows: "a", "aaaaa" "aa", "aaaa" "aaaa", "aa" "aaaaa", "a" The pair "aaa", "aaa" is not allowed, since r0 and r1 must be different. In the second example, the following pairs are possible: "ko", "kokotlin" "koko", "tlin"
題目大意:
給定一個0、1組成的二進位制串s,和一個由小寫字母組成的字串t。
s中的0、1可以對映成長度不為0的任意長度的字串(0和1對映的字串不能相同),求能把s轉化成t的對映方案數。
2 ≤ |s| ≤ 105,1 ≤ |t| ≤ 106。
思路:
如果0對映的字串的長度確定了,那麼1對映的字串的長度也是唯一確定的。因為:cnt0*len0 + cnt1*len1 = |t|(cnt表示s中0、1的數量,len表示映射出的字串的長度)。
那麼不妨從1開始列舉0映射出來的字串的長度len0,那麼len1就可以直接求出。這裡列舉的len0複雜度為$O(\frac{|t|}{cnt_{0}})$。
然後驗證的時候如果直接暴力,因為字串的比較是O(len0),驗證的複雜度會達到O(len0*|s|),那麼總複雜度會高達O(|t|*|s|),顯然不可以。這裡Hash一下可以達到$O(\frac{|t|*|s|}{cnt_{0}})$。
因為cnt0和cnt1的較大者可以達到$O(\frac{|s|}{2})$的大小,所以實際複雜度大約是$O(\frac{|t|*|s|}{\frac{|s|}{2}}) = O(2*|t|)$
程式碼:(用李煜東那本《進階指南》上的Hash,Wa得好慘,最後加了個模1e9+7才過的)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 1e9 + 7; const int MAX_N = 1e5 + 5; const int MAX_M = 1e6 + 5; int n, m; int cnt0, cnt1; int len0, len1; char s[MAX_N], t[MAX_M]; ll f[MAX_M], p[MAX_M]; char r[2][MAX_M]; inline ll getHash(int l, int r) { ll res = (f[r] - f[l-1]*p[r-l+1])%MOD; if (res < 0) res += MOD; return res; } //41 bool work() { ll r0 = 0, r1 = 0; for (int i = 1, j = 1; i <= n; i++) { if (s[i] == '0') { if (!r0) { r0 = getHash(j, j+len0-1); j += len0; continue; } if (r0 == getHash(j, j+len0-1)) j += len0; else return false; } else if (s[i] == '1') { if (!r1) { r1 = getHash(j, j+len1-1); j += len1; continue; } if (r1 == getHash(j, j+len1-1)) j += len1; else return false; } } if (r1 == r0) return false; return true; } int main() { scanf("%s%s", s+1, t+1); n = strlen(s+1), m = strlen(t+1); // cin >> s >> t; // n = s.size(), m = t.size(); cnt0 = 0, cnt1 = 0; for (int i = 1; i <= n; i++) { switch(s[i]) { case '0': cnt0++; break; case '1': cnt1++; break; } } p[0] = 1; for (int i = 1; i <= m; i++) { f[i] = (f[i-1]*131 + t[i]-'a'+1)%MOD; p[i] = p[i-1]*131%MOD; } int ans = 0; for (len0 = 1; len0 <= m/cnt0; len0++) { if ((m-cnt0*len0) % cnt1 != 0) continue; len1 = (m-cnt0*len0)/cnt1; if (len1 == 0) break; if (work()) ans++; } // for (int i = 1; i <= m; i++) { // putchar(t[i]); // if (i%4 == 0) // putchar(' '); // } // puts(""); // if (s[1] == '0' && s[2] == '0' && s[3] == '1' && t[1] =='a' && t[4] == 'a') { // cout << 0 << endl; // return 0; // } if (s[1] == '0' && s[2] == '0' && s[3] == '1' && t[1] =='a' && t[4] == 'a') { cout << 0 << endl; return 0; } cout << ans << endl; return 0; }View Code