• Codeforces1056E.Check Transcription(枚举+Hash)


    题目链接:传送门

    题目:

    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 they'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 as easy 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" 
    View Code

    题目大意:

      给定一个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
  • 相关阅读:
    计算机网络-URL/URI/URN
    计算机网络-应用层之HTTP协议
    计算机网络-传输层-TCP之三次握手/四次握手
    requests之一:HTTP请求 状态码
    python排序中sort()与sorted()的用法与区别
    列表(list)之三 -如何较为均匀的将任意字符串按指定组数分组,方差最少
    列表(list)之二 -运用篇 -快速生成规律性列表
    DES加密解密
    c# json转Dictionary字典
    导出Excel事例
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/10051095.html
Copyright © 2020-2023  润新知