当前位置: 首页 > news >正文

CF1056E Check Transcription 题解

题意简析

给你一个 \(01\)\(s\),字母串 \(t\),用两个不同且非空的字符串 \(r_0\)\(r_1\) 分别替换 \(s\) 中的所有 \(0\)\(1\),使 \(t\),求满足条件的 \((r_0, r_1)\) 的数量。

思路解析

因为 \(0\)\(1\) 的数量和总的目标串长度是固定的,所以考虑枚举 \(0\)\(1\) 中较多的长度,然后再检查是否满足条件。

为什么这里要枚举较多的?

因为发现这一个过程很可能是 \(O(nm)\) 的,所以需要优化。

可以类比为一个线性方程组,这里为方便讨论设 \(a > b > 0\)\(m,n > 0\)

\[ax + b(n-x) = m \]

就有

\[ax + bn = bx + m \]

根据我们初中数学知识知道,直线的斜率的绝对值越大,直线越倾斜,那么其与坐标轴的两个交点的横坐标的差值也会越小,即 \(\frac{c}{b} < \frac{c}{a}\),枚举的 \(x\) 也就越少。

上界不会超过 \(\frac{m}{n}\),这样的复杂度就大大降低了。


但我们怎么快速查询 \(t\) 的子串是否合法呢?我们想到了用哈希。

哈希是可以 \(O(1)\) 查询子串是否相同的,因为题目中说要用不同且非空的字符串。但是这题用自然溢出哈希显然会被卡(毕竟看看是哪个 OJ 出的比赛),所以我们要用双哈希或者随机化。


如果每次快速幂求底数的幂次,那么查询一多就显得很浪费而且带个 \(\log\);但如果递推求底数的幂次就不会有这个问题。

别忘了特判 \(r_0 = r_1\) 的情况。

时空复杂度为 \(O(m)\)

代码实现

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int M = 1e6 + 5, Base1 = 131, Base2 = 137, Mod1 = 1e9 + 9, Mod2 = 1e9 + 7;
int n, m, pow1[M], pow2[M], h1[M], h2[M], lx, ly, ans, cnt0, cnt1;
char x = '0', y = '1';
string s, t;
namespace Mathematics {
inline int qpow(int a, int b, int MOD) {int res = 1;while (b) {if (b & 1) {res = res * a % MOD;}a = a * a % MOD;b >>= 1;}return res;
}
} // namespace Mathematics
inline void Init() {pow1[0] = pow2[0] = 1;for (int i = 1; i <= m; i++) {pow1[i] = pow1[i - 1] * Base1 % Mod1;pow2[i] = pow2[i - 1] * Base2 % Mod2;}h1[0] = h2[0] = 0;for (int i = 1; i <= m; i++) {h1[i] = (h1[i - 1] * Base1 + t[i - 1]) % Mod1;h2[i] = (h2[i - 1] * Base2 + t[i - 1]) % Mod2;}return;
}
inline pair<int, int> get_hash(int l, int r) {int hash1 = (h1[r] - h1[l] * pow1[r - l] % Mod1 + Mod1) % Mod1;int hash2 = (h2[r] - h2[l] * pow2[r - l] % Mod2 + Mod2) % Mod2;return {hash1, hash2};
}
inline bool check() {int now = 0, px = -1, py = -1;pair<int, int> hashx, hashy;for (int i = 0, l, r; i < n; i++) {if (s[i] == x) {l = now, r = now + lx;pair<int, int> h = get_hash(l, r);if (px == -1) {hashx = h;px = l;} else if (h != hashx) {return false;}now = r;} else {l = now, r = now + ly;pair<int, int> h = get_hash(l, r);if (py == -1) {hashy = h;py = l;} else if (h != hashy) {return false;}now = r;}}if (hashx == hashy) {if (lx == ly) {if (t.substr(px, lx) == t.substr(py, ly)) {return false;}}}return true;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cin >> s >> t;n = s.size(), m = t.size();Init();cnt0 = count(s.begin(), s.end(), '0'), cnt1 = n - cnt0;if (cnt0 < cnt1) {swap(x, y);swap(cnt0, cnt1);}for (lx = 1; lx <= m; lx++) {int totx = cnt0 * lx;if (totx >= m) {break;}int rem = m - totx;if (!(rem % cnt1)) {ly = rem / cnt1;if (ly > 0) {ans += check();}}}cout << ans << "\n";return 0;
}

后记

还记得滴叉在去年暑假的某节字符串课讲过,出题人卡不卡自然溢出哈希纯看良心。但如果你用双哈希再加上 std::mt19937\(10^9\) 级别的随机选取大质数,那么发生哈希冲突的概率比你被飞机创的概率还低。

当然,Codeforces 的出题人和其他选手肯定会卡你的自然溢出哈希,所以建议大家还是多用用双哈希(毕竟 Hash Killer III 还没有人做出来过)。

http://www.jsqmd.com/news/321647/

相关文章:

  • 2026年手机膜工厂推荐:基于跨境与代工场景深度评测,解决品质与交付核心痛点
  • 2026热门的全面预算管理系统源头厂家哪家好
  • 厦门室内装修公司大揭秘:实力榜单助你打造理想家
  • 2026年高端酒店设计公司推荐:打造品质旅居空间
  • 长沙小学私立学校哪家靠谱,年度排名为您揭晓优质学校
  • 天津一鑫时尚假发补发私人定制 联系方式:客观评估定制需求与风险
  • 基于单片机的数字时钟设计(有完整资料)
  • 2026年全屋定制品牌专项测评:选型指引方向
  • 高性价比的旧房翻新品牌企业哪家好,廊坊富迪装饰值得关注
  • 2026年手机膜工厂推荐:跨境与定制化需求深度评价,直击产能与合规痛点
  • 衣柜除湿照明(有完整资料)
  • 搭便车,是实用的生活智慧
  • 2026年众信旅游推荐:基于行业地位与资源整合能力的深度评测与排名
  • 2026年手机膜工厂推荐:多场景应用深度评价,针对定制化与产能痛点精准指南
  • 分享艺术涂料漆代理加盟经验,玛斯涂成行业热门选择
  • ‌AI驱动的竞品App对比测试用例自动生成
  • 基于大数据hadoop+spark二手房房价预测与分析系统 机器学习实战
  • VMware替换关键技术:核心业务系统中,访存密集型应用的性能优化
  • 支付宝红包套装闲置不用慌,高效盘活攻略请收好
  • 解锁工业制造黑科技:在线视觉检测与激光工艺闭环控制
  • 仿石漆选购,推荐玛斯涂这个性价比高的靠谱品牌
  • 2026年抛丸机推荐:基于多行业应用场景评价,针对清理效率与定制化需求
  • CTF选手必藏的100个实战解题思路,从零基础到精通,收藏这篇就够了!
  • hadoop+spark+Python租房大数据分析可视化系统
  • 抛丸机哪个品牌更可靠?2026年抛丸机推荐与评价,涵盖多场景应用
  • 【Frida Android】实战篇5:SSL Pinning 证书绑定绕过 Hook 教程(二) - 教程
  • 行业视角:2026年河道护坡石笼网优质生产商分析,柔韧抗压石笼网/六角石笼网/双隔板石笼网,河道护坡石笼网源头厂家哪个好
  • 2026办公室翻新公司推荐:资质与服务能力综合解析
  • AI元人文九大论:面向智能文明的思想操作系统
  • 从月度账单里,盘活支付宝红包套装的沉默价值