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

【CCPC】CCPC 2023 Shenzhen Site G

Gene

#二分 #哈希 #字符串

题目描述

Let s s s and t t t be two strings with equal lengths M M M . Define f ( s , t ) = ∑ i = 1 M [ s i ≠ t i ] f (s, t) =\sum_{i=1}^M[s_i\neq t_i] f(s,t)=i=1M[si=ti]
You are given N N N strings s 1 , s 2 , ⋅ ⋅ ⋅ , s N s_1, s_2, · · · , s_N s1,s2,⋅⋅⋅,sN and a constant threshold K K K. Each of the string contains exactly M M M lowercase letters. You need to perform the following queries Q Q Q times:

• • Given a string t t t of length M M M , calculate ∑ i = 1 N [ f ( s i , t ) ≤ K ] \sum_{i=1}^N[f (s_i, t)\leq K] i=1N[f(si,t)K]

输入格式

The first line of the input contains four integers N N N, Q Q Q, M M M, and K K K ( 1 ≤ N , Q ≤ 300 , 1 ≤ M ≤ 60 , 000 , 1 ≤ K ≤ 10 ) . 1 ≤ N, Q ≤ 300, 1 ≤ M ≤ 60, 000,1 ≤ K ≤ 10). 1N,Q300,1M60,000,1K10).
The i − i- ith line of the next N N N lines contains a single string si consisting exactly M M M lowercase letters.
The i − i- ith line of the next Q Q Q lines contains a single string t t t consisting exactly M M M lowercase letters, indicating a query.

输出格式

For each query, output a single line contains a single integer, indicating the answer

样例 #1

样例输入 #1

6 4 4 1
kaki
kika
manu
nana
tepu
tero
kaka
mana
teri
anan

样例输出 #1

2
2
1
0

解法

解题思路

观察到 k ≤ 10 k\leq 10 k10,因此我们可以对字符串进行哈希,枚举 n n n个匹配串,然后每次二分出第 i ( i ≤ k ) i(i\leq k) i(ik)个不同的位置,如果能二分到最后的位置,那么这个匹配串就为合法的串了。

为了减少哈希碰撞,这里我们的哈希使用的是随机模数的哈希。

这样整体的时间复杂度在 O ( m q + n k l o g 2 m ) O(mq+nklog_2m) O(mq+nklog2m)

代码


mt19937_64 rng((unsigned int)chrono::steady_clock::now().time_since_epoch().count());struct hash61 {hash61() {}static const uint64_t md = (1LL << 61) - 1;static uint64_t step;static vector<uint64_t> pw;uint64_t addmod(uint64_t a, uint64_t b) const {a += b;if (a >= md) a -= md;return a;}uint64_t submod(uint64_t a, uint64_t b) const {a += md - b;if (a >= md) a -= md;return a;}uint64_t mulmod(uint64_t a, uint64_t b) const {uint64_t l1 = (uint32_t)a, h1 = a >> 32, l2 = (uint32_t)b, h2 = b >> 32;uint64_t l = l1 * l2, m = l1 * h2 + l2 * h1, h = h1 * h2;uint64_t ret = (l & md) + (l >> 61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1;ret = (ret & md) + (ret >> 61);ret = (ret & md) + (ret >> 61);return ret - 1;}void ensure_pw(int sz) {int cur = (int)pw.size();if (cur < sz) {pw.resize(sz);for (int i = cur; i < sz; i++) {pw[i] = mulmod(pw[i - 1], step);}}}vector<uint64_t> pref;int n;template<typename T>hash61(const T& s) {n = (int)s.size();ensure_pw(n + 1);pref.resize(n + 1);pref[0] = 1;for (int i = 0; i < n; i++) {pref[i + 1] = addmod(mulmod(pref[i], step), s[i]);}}inline uint64_t operator()(const int from, const int to) const {assert(0 <= from && from <= to && to <= n - 1);return submod(pref[to + 1], mulmod(pref[from], pw[to - from + 1]));}
};
uint64_t hash61::step = (md >> 2) + rng() % (md >> 1);
vector<uint64_t> hash61::pw = vector<uint64_t>(1, 1);void solve() {int n, q, m, k;std::cin >> n >> q >> m >> k;std::vector<hash61>a(n + 1);for (int i = 1; i <= n; ++i) {std::string s;cin >> s; s = " " + s;a[i] = hash61(s);}while (q--) {std::string s;std::cin >> s;s = " " + s;auto b = hash61(s);int res = 0;for (int i = 1; i <= n; ++i) {int L = 1, R = m;for (int j = 1; j <= k; ++j) {int l = L, r = R, ans = -1;while (l <= r) {int mid = l + r >> 1;if (b(l, mid) == a[i](l, mid)) {ans = mid;l = mid + 1;}else {r = mid - 1;}}if (ans == -1) L++;else L = ans + 2;}if (L > m) ++res;else {if (b(L, m) == a[i](L, m)) ++res;}}std::cout << res << "\n";}}
signed main() {std::ios::sync_with_stdio(0);std::cin.tie(0);std::cout.tie(0);int t = 1;//std::cin >> t;while (t--) {solve();}
}

http://www.mrgr.cn/news/48345.html

相关文章:

  • Java模拟Mqtt客户端连接Mqtt Broker
  • 使用 datamodel-code-generator 从 MySQL 生成 Python 模型
  • Vue.js前端框架教程11:Vue监听器watch和watchEffect
  • Python 助力 DBA:高效批量管理数据库服务器的多线程解决方案-多库查询汇总工具实现
  • AI开发-语料-“self-instruct”
  • 三维激光扫描大尺寸工件长度检测
  • .NET MAUI 手搓 UDP/TCP 通信
  • 萱仔求职复习系列——力扣
  • 《 C++ 修炼全景指南:十五 》突破算法极限:并查集如何轻松搞定最棘手的连通性问题?
  • 《深度学习》【项目】OpenCV 答题卡识别 项目流程详解
  • QD1-P4 HTML标题标签(h)水平线标签(hr)
  • dd 工具 是一个在 Linux 系统中用于复制文件和转换文件的工具
  • vue后台管理系统从0到1(2)
  • Basic penetration_1靶机渗透
  • 数据结构——树和森林
  • Bob_ 1.0.1靶机渗透
  • Linux `sort` 命令详解
  • 【Python】Python实现串口通信(Python+Stm32)
  • 1374. 生成每种字符都是奇数个的字符串
  • 18708 最大子段和
  • ARM学习(32)FreeRTOS 调度和timer流程
  • Java->Map和Set
  • Jave常用的类---String类
  • 英语中 ing后缀
  • BUG修复(不断整理想起什么就整理什么)
  • Java中的流:高效处理数据的新方式