首页 > 其他分享 >P10992 Solution

P10992 Solution

时间:2024-10-18 22:01:20浏览次数:8  
标签:cnt int Solution len base 哈希 字符串 P10992

Description

Link

Solution

好题。

本题主要有两个问题:哈希函数的设计和子串的枚举。

作为哈希题的套路,首先可以想到二分答案长度,再做 check

考虑如何设计哈希函数来 check。令二分出的长度为 \(len\)。

设计出的哈希函数需要满足两个条件:两个串对应的字符集相同,对应字符集的下标相同。默认字符集可重。

考虑以下哈希函数:

令 \(g(i)\) 为表示从 \(i\) 到 \(i + len - 1\) 这一段字符串的所有字母的哈希值,具体怎么设计待会再说。

令 \(h(i)\) 表示从 \(i\) 到 \(i + len - 1\) 这一段字符串 \(g(i)\) 的哈希值,即 \(\begin{aligned} h(i) = \bigoplus^{i+len-1}_{j=1} g(j)\end{aligned}\)。

对于两个字符串,分别求解哈希值,对于每个第一个字符串的哈希值,只需要找到第二个字符串的哈希值就可以了。这部分可以对第二个字符串的哈希值排序,然后二分,枚举子串的问题就解决了。

接下来,思考一个问题:哈希函数 \(g(i)\)。

可以考虑一个类似于滑动窗口的转移:对于当前字符串的子串 \([i, i + len - 1]\),对于每一个下标赋一个权值 \(w_j\),即对于每一个 \(j = [i, i + len - 1]\),\(w_j=j-i+1\)。

比如说字符串 aba,对于字符 a,其权值为 \(base^1+base^3\);对于字符 b,其权值为 \(base^2\)。

Code

// PikachuQAQ 2024/10/18

#include <bits/stdc++.h>

using namespace std;
using ull = unsigned long long;

const int kN = 1e5 + 2, base = 137;

int n, m, mx, mi, ans;
string s, t;
ull has1[kN], has2[kN], bpow[kN], cnt[30];

void solve(string s, int l, int r) {
    fill(cnt, cnt + 30, 0);
    for (int i = l; i <= r; i++) {
        cnt[s[i] - 'a'] += bpow[i - l + 1];
    }
}

void solve_hash(int l) {
    has1[l] = 0;
    for (int i = 0; i < 26; i++) {
        has1[l] ^= cnt[i];
    }
}

bool check(int len) {
    solve(t, m - len + 1, m), solve_hash(m - len + 1);
    for (int l = m - len, r = m - 1; l >= 1; l--, r--) {
        cnt[t[r + 1] - 'a'] -= bpow[len];
        for (int i = 0; i < 26; i++) cnt[i] *= base;
        cnt[t[l] - 'a'] += base;
        solve_hash(l);
    }
    for (int i = 1; i <= m - len + 1; i++) {
        has2[i] = has1[i];
    }
    solve(s, n - len + 1, n), solve_hash(n - len + 1);
    for (int l = n - len, r = n - 1; l >= 1; l--, r--) {
        cnt[s[r + 1] - 'a'] -= bpow[len];
        for (int i = 0; i < 26; i++) cnt[i] *= base;
        cnt[s[l] - 'a'] += base;
        solve_hash(l);
    }
    sort(has2 + 1, has2 + m - len + 2);
    for (int i = 1, res; i <= n - len + 1; i++) {
        if (binary_search(has2 + 1, has2 + m - len + 2, has1[i])) return 1;
    }
    return 0;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> s >> t;
    n = s.size(), m = t.size(), mx = max(n, m), mi = min(n, m);
    s = " " + s, t = " " + t;
    bpow[0] = 1;
    for (int i = 1; i <= mx; i++) {
        bpow[i] = bpow[i - 1] * base;
    }
    for (int l = 1, r = mi, mid; l <= r; ) {
        mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid + 1, ans = mid;
        } else {
            r = mid - 1;
        }
    }
    cout << ans;

    return 0;
}

标签:cnt,int,Solution,len,base,哈希,字符串,P10992
From: https://www.cnblogs.com/PikachuQAQ/p/18475130/P10992

相关文章

  • 【题解】Solution Set - NOIP2024集训Day56 哈希杂题
    【题解】SolutionSet-NOIP2024集训Day56哈希杂题https://www.becoder.com.cn/contest/5640「CF568C」NewLanguage做过的2-sat。「NOI2024」集合做过。做法见提交记录。「CSP-S2022」星战简要题意:给定有向图。修改使一条边失效/恢复;使一个点的所有入边......
  • Solution - Codeforces 1628D2 Game on Sum (Hard Version)
    首先来考虑Easy。注意到的是最后输出的答案要求是模意义下的,这说明对于实数二分的做法都已经用不了了。注意到\(n,m\le3000\)的数据范围,于是一个想法就是考虑DP之类的算法。考虑到B选了\(+/-\)实际上就代表着下一轮的\(m\)是否会\(-1\),于是可以设状态为\(f_{i......
  • 【题解】Solution Set - NOIP2024集训Day50 图的连通性相关
    【题解】SolutionSet-NOIP2024集训Day50图的连通性相关https://www.becoder.com.cn/contest/5618「JSOI2012」越狱老虎桥简述题意:题目大意:给定一张图,A先添加\(1\)条边,B再删去一条边使得图不连通,A要最大化删除边的权值,B要最小化删除边的权值,问最终的权值是多少。......
  • AME 209/MSE 280 solution
    AME209/MSE280Homework4Fall2024Thehomework4solutionwillonlyincludetwom-files,oneforeachofthefollowingproblems.NoPDFwriteupisneededforthisassignment.Nameyoursolutionfiles:hw04_prob1_NNNN.mhw04_prob2_NNNN.msubstitutingthelast......
  • Solution - Codeforces 622E Ants in Leaves
    首先因为\(1\)点是可以一次性到多个点的,因此不需要考虑\(1\)点的情况,而是转而分析\(1\)的每个子树的情况,最后取\(\max\)。那么对于每个子树,就有每个节点每个时刻至多存在\(1\)个点的性质了。考虑如何去求解。首先一个贪心的想法是肯定是每个蚂蚁越早到一个点越好。于......
  • PageRank parallel solutions
    Assignment4 DueFridayby11:59pmPoints70 SubmittingafileuploadAvailableOct4at12am-Dec24at11:59pmStartAssignment Assignment4(70Points) ueFridayOctober11@11:59PMInthisassignment,wewillimprovetheparallelsolutionsofPageRa......
  • Solution - Atcoder ARC116C Multiple Sequences
    一个\(\mathcal{O}(m^{\frac{3}{4}}\logm)\)做法。令\(a_0=1\)。对于倍数问题,考虑类似差分的思想,定义\(b_i=\frac{a_i}{a_{i-1}}(1\lei\len)\),那么合法的\(a\)和\(b\)是双射的,就只需要考虑对\(b\)计数了。考虑到因为有\(\prod\limits_{i=1}^nb_i\lem\)......
  • redis scalable solution -- twemproxy
    twemproxyhttps://github.com/twitter/twemproxyAfast,light-weightproxyformemcachedandredistwemproxy(nutcracker)twemproxy(pronounced"two-em-proxy"),akanutcrackerisafastandlightweightproxyformemcachedandredisprotocol.......
  • 【题解】Solution Set - NOIP2024集训Day42 博弈论
    【题解】SolutionSet-NOIP2024集训Day42博弈论https://www.becoder.com.cn/contest/5574https://www.cnblogs.com/CloudWings/p/17813917.html「中山市选2009」谁能赢呢?一道经典的「二分图博弈」在棋盘问题上的应用。https://www.luogu.com.cn/article/h8a79k3i......
  • CF2018E2 Solution
    CF2018E2Solution先考虑E1的做法。首先我们如果钦定一组\(k\)条线段的话,容易求出最大组数。简单来讲就是将所有端点按照右端点排序,这样只需要考虑一个偏序,然后扫描,将区间\([l_i,r_i]\)加一,当发现某个点的值为\(k\)时,就说明分成了一组方案。此时我们一定清空,然后记录当......