题目:

CodeForces727E

分析:

看到字符串比较,肯定想到哈希啊……现学的哈希,先丢两个重要的公式

(\(seed\)是大于字符集大小的质数,\(p\)是大质数)

\[hash[i]=(hash[i-1]*seed+s[i])mod \ p
\]

\[hash[l,r]=(hash[r]-hash[l-1]*seed^{r-l+1})mod \ p
\]

把哈希想象成\(seed\)进制数,第二个公式很容易推出来。注意写的时候要防止出现负数(详见代码)

为了降低取模后不同字符串获得相同哈希值 ("冲突") 的可能性,这里分别对两个不同的\(p\)取模,即“双哈希”。

既然原字符串是一个“环”,那么自然能想到将其复制一份接在原串末尾,然后枚举起始位置。由于模板串长\(k\)一定,且原串每一位都应该匹配,那么显然当起始位置一定则方案一定,且只需要枚举原串前\(k\)个位置作为起始位置即可讨论到所有情况。

对于每一个起始位置可以\(O(n)\)找出每一个位置的匹配方案,因此最终时间复杂度是\(O(nk)\)

代码:

不能不取模,也不能乱取模;不能偷懒直接把str倍长……否则就会像我一样在CF上惨遭卡常233

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
using namespace std; namespace zyt
{
typedef long long ll;
typedef pair <ll, ll> pll;
const int N = 1e6 + 10, seed = 131, p[2] = {(int)1e9 + 7, (int)1e9 + 9};
ll F[N * 2][2], h[N * 2][2];
string str;
map <pll, int> id;
inline void init(const string &str)
{
F[0][0] = F[0][1] = 1;
for (int i = 1; i < str.size(); i++)
{
F[i][0] = F[i - 1][0] * seed % p[0];
F[i][1] = F[i - 1][1] * seed % p[1];
}
h[0][0] = h[0][1] = str[0] - 'a';
for (int t = 0; t < 2; t++)
for (int i = 1; i < str.size(); i++)
h[i][t] = (h[i - 1][t] * seed + str[i] - 'a') % p[t];
}
inline pll Hash(const string &s)
{
ll ans[2] = {0, 0};
for (int t = 0; t < 2; t++)
for (int i = 0; i < s.size(); i++)
ans[t] = (ans[t] * seed + s[i] - 'a') % p[t];
return make_pair(ans[0], ans[1]);
}
inline pll Hash(const int l, const int r)
{
int len = r - l + 1;
if (l == 0)
return make_pair(h[r][0], h[r][1]);
else
return make_pair(
(h[r][0] - h[l - 1][0] * F[len][0] % p[0] + p[0]) % p[0],
(h[r][1] - h[l - 1][1] * F[len][1] % p[1] + p[1]) % p[1]);
}
void work()
{
int n, k, g, len;
static char buf[N];
string str;
bool flag = false;
scanf("%d%d", &n, &k);
len = n * k;
scanf("%s", buf);
str = buf;
str += str.substr(0, k);
init(str);
scanf("%d", &g);
for (int i = 0; i < g; i++)
{
scanf("%s", buf);
str = buf;
id[Hash(str)] = i;
}
static int ans[N], vis[N];
memset(vis, -1, sizeof(vis));
for (int i = 0; i < k && !flag; i++)
{
pll p;
int cnt = 0;
for (int j = i; j < len + i && cnt < n; j += k)
if (id.count(p = Hash(j, j + k - 1)) && vis[id[p]] != i)
ans[cnt++] = id[p], vis[id[p]] = i;
else
break;
if (cnt == n)
flag = true;
}
if (flag)
{
printf("YES\n");
for (int i = 0; i < n; i++)
printf("%d ", ans[i] + 1);
}
else
printf("NO\n");
}
}
int main()
{
zyt::work();
return 0;
}

【CodeForces727E/CF727E】Games on a CD (字符串哈希)的更多相关文章

  1. CodeForces - 727E Games on a CD 字符串Hash

    题意:有n个单词,每个单词长度为k,顺时针将它们写成一个圆圈串.现在知道g个长度为k的单词,是否可以从这g个单词中选择n个形成这个圆圈串?如果有多个答案,任意输出一个. 思路 可以发现,如果枚举第一个 ...

  2. Games on a CD

    Games on a CD time limit per test 4 seconds memory limit per test 512 megabytes input standard input ...

  3. HDU 1880 魔咒词典(字符串哈希)

    题目链接 Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一 ...

  4. 洛谷P3370 【模板】字符串哈希

    P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...

  5. HDU2594 Simpsons’ Hidden Talents 字符串哈希

    最近在学习字符串的知识,在字符串上我跟大一的时候是没什么区别的,所以恶补了很多基础的算法,今天补了一下字符串哈希,看的是大一新生的课件学的,以前觉得字符串哈希无非就是跟普通的哈希没什么区别,倒也没觉得 ...

  6. LA 6047 Perfect Matching 字符串哈希

    一开始我用的Trie+计数,但是不是计多了就是计少了,后来暴力暴过去的…… 看了别人的代码知道是字符串哈希,但是仍有几个地方不理解: 1.26^500溢出问题 2.没考虑哈希碰撞? 跪求指点! #in ...

  7. AC日记——【模板】字符串哈希 洛谷 3370

    题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转 ...

  8. 从Hash Killer I、II、III论字符串哈希

    首先,Hash Killer I.II.III是BZOJ上面三道很经典的字符串哈希破解题.当时关于II,本人还琢磨了好久,但一直不明白为啥别人AC的代码都才0.3kb左右,直到CYG神犇说可以直接随机 ...

  9. 【NOIP模拟】Grid(字符串哈希)

    题目背景 SOURCE:NOIP2016-RZZ-1 T3 题目描述 有一个 2×N 的矩阵,矩阵的每个位置上都是一个英文小写字符. 现在需要从某一个位置开始,每次可以移动到一个没有到过的相邻位置,即 ...

随机推荐

  1. C. Day at the Beach

    codeforces 599c C. Day at the Beach One day Squidward, Spongebob and Patrick decided to go to the be ...

  2. 使用Mybatis的逆向工程自动生成代码

    1.逆向工程的作用 Mybatis 官方提供了逆向工程,可以针对数据库表自动生成Mybatis执行所需要的代码(包括mapper.xml.Mapper.java.pojo). 2.逆向工程的使用方法 ...

  3. Spring使用DriverManagerDataSource和C3P0分别配置MySql6.0.6数据源

    首先,看一下项目路径 先说spring配置文件吧,这个比较重要 <?xml version="1.0" encoding="UTF-8"?> < ...

  4. BZOJ 1853

    http://www.lydsy.com/JudgeOnline/problem.php?id=1853 岛娘在空间上发的题解就看了看果然被骗了.还以为是数位dp. 原来是容斥啊.好吧第一道正式的题目 ...

  5. poj 1562 简单深搜

    //搜八个方向即可 #include<stdio.h> #include<string.h> #define N 200 char ma[N][N]; int n,m,vis[ ...

  6. HDU——1023 Train Problem II

    Train Problem II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. Vue插槽的另外一些特性

    之前有个项目,想判断一下,某一个模板内的插槽是否被使用. 不知道是不是问题过于简单,网上没有这方面的说明.我就抽时间验证一下vue插槽相关的一些功能. 然后写下这篇随笔,希望对后来人能有一些帮助. 简 ...

  8. Spring mvc+Easyui遇到的几个问题

    简单的一个数据表的增删查改的总体界面的展示效果例如以下图: 1.datagrid数据载入问题 datagrid通过url请求后台数据,总记录数和数据行的属性是固定死的.数据行是rows,总记录数为to ...

  9. vector实现

    typedef int size_type; /* vector维护的是一个连续线性空间,提供的迭代器是Random Access Iterators即普通指针 */ template <cla ...

  10. 从零单排入门机器学习:Octave/matlab的经常使用知识之矩阵和向量

    Octave/matlab的经常使用知识之矩阵和向量 之前一段时间在coursera看了Andrew ng的机器学习的课程,感觉还不错.算是入门了.这次打算以该课程的作业为主线,对机器学习基本知识做一 ...