http://codeforces.com/gym/101138/problem/A

感觉有一种套路就是总长度 <= 某一个数的这类题,大多可以分块

首先把集合串按长度分块,对于每一个询问串,

在 > magic的big集合里,因为最多sqrtn个,可以暴力枚举每一个,然后暴力枚举询问串的每一个长度是其的子串,判断是否相等

在 <= magic的small集合里,枚举每一个长度是magic, magic-1, magic-2, magic-3........1的字符串,然后看看是否在small集合里存在

small集合用unordermap保存即可。

ps

判断map是否存在一个元素,用mp.find

不然用mp[]每次都会生成一个节点,然后MLE, 清空用mp.erase

不然Mp.find是true的

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef unsigned long long int ULL; const int seed = ;
const int maxn = + ;
struct Node {
ULL hs;
int lenstr;
Node(ULL _hs, int _lenstr) {
hs = _hs, lenstr = _lenstr;
}
bool operator < (const Node & rhs) const {
if (hs != rhs.hs) return hs > rhs.hs;
else return lenstr > rhs.lenstr;
}
};
vector<Node> all;
set<Node> ss;
unordered_map<ULL, bool> mp;
char str[maxn];
int magic;
set<Node> :: iterator it;
void addchar(int id, char ch) {
// set<Node> :: iterator it;
if (all[id].lenstr > magic) {
ss.erase(ss.find(all[id]));
all[id].lenstr++;
all[id].hs = all[id].hs * seed + ch;
ss.insert(all[id]);
} else {
if (all[id].lenstr == magic) {
mp.erase(all[id].hs);
// mp[all[id].hs] = false;
all[id].lenstr++;
all[id].hs = all[id].hs * seed + ch;
ss.insert(all[id]);
} else {
mp.erase(all[id].hs);
all[id].lenstr++;
all[id].hs = all[id].hs * seed + ch;
mp[all[id].hs] = true;
}
}
}
ULL po[maxn];
ULL sum[maxn];
int last_yes;
bool ok() {
int lenstr = strlen(str + );
for (int i = ; i <= lenstr; ++i) {
str[i] = (str[i] - 'a' + last_yes) % + 'a';
sum[i] = sum[i - ] * seed + str[i];
}
for (it = ss.begin(); it != ss.end(); ++it) {
int len = it->lenstr;
for (int j = len; j <= lenstr; ++j) {
if (it->hs == sum[j] - po[len] * sum[j - len]) return true;
}
}
for (int i = ; i <= lenstr; ++i) {
for (int c = ; c <= magic && c <= i; ++c) {
if (mp.find(sum[i] - po[c] * sum[i - c]) != mp.end()) return true;
}
}
return false;
} void work() {
int n, q;
scanf("%d%d", &n, &q);
magic = (int)sqrt(n * 1.0);
for (int i = ; i <= n; ++i) {
scanf("%s", str + );
ULL hashVal = ;
int lenstr = strlen(str + );
for (int j = ; j <= lenstr; ++j) {
hashVal = hashVal * seed + str[j];
}
if (lenstr > magic) ss.insert(Node(hashVal, lenstr));
else {
mp[hashVal] = true;
}
all.push_back(Node(hashVal, lenstr));
}
last_yes = ;
for (int i = ; i < q; ++i) {
int op;
scanf("%d", &op);
if (op == ) {
int index, ch;
scanf("%d%d", &index, &ch);
addchar((index + last_yes) % n, (ch + last_yes) % + 'a');
} else {
scanf("%s", str + );
if (ok()) {
printf("YES\n");
last_yes = i;
} else printf("NO\n");
}
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
po[] = ;
for (int i = ; i <= maxn - ; ++i) po[i] = po[i - ] * seed;
work();
return ;
}

A. Yet Another Problem with Strings 分块 + hash的更多相关文章

  1. Codeforces Round #FF (Div. 2):Problem A - DZY Loves Hash

    A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  2. hdu_5085_Counting problem(莫队分块思想)

    题目连接:hdu_5085_Counting problem 题意:给你一个计算公式,然后给你一个区间,问这个区间内满足条件的数有多少个 题解:由于这个公式比较特殊,具有可加性,我们考虑讲一个数分为两 ...

  3. POJ 3468 A Simple Problem with Integers(分块入门)

    题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit ...

  4. Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

    一.题目 D. Yet Another Subarray Problem 二.分析 公式的推导时参考的洛谷聚聚们的推导 重点是公式的推导,推导出公式后,分块是很容易想的.但是很容易写炸. 1 有些地方 ...

  5. POJ3468 a simple problem with integers 分块

    题解:分块 解题报告: 是个板子题呢qwq 没什么可说的,加深了对分块的理解趴还是 毕竟这么简单的板子题我居然死去活来WA了半天才调出来,,,哭了QAQ 还是说下我错在了哪几个地方(...是的,有好几 ...

  6. CF985F Isomorphic Strings (字符串Hash,巧解)

    题目链接 题意翻译 给你一个长度为 \(n\) 的字符串,\(m\) 次询问. 问两个相同长度的子串是否匹配. 我们称两个子串是匹配的,当且仅当其满足: 其中一个子串的字母可替代另一个子串的字母 例如 ...

  7. POJ 3468 A Simple Problem with Integers (分块)

    Description You have \(N\) integers, \(A_1, A_2, ... , A_N\). You need to deal with two kinds of ope ...

  8. CodeForces 165C Another Problem on Strings(组合)

    A string is binary, if it consists only of characters "0" and "1". String v is a ...

  9. Day8 - C - Another Problem on Strings CodeForces - 165C

    A string is binary, if it consists only of characters "0" and "1". String v is a ...

随机推荐

  1. WordCount-软件测试初体验

    github:https://github.com/skz12345/WordCount PSP2.1 PSP阶段 预估耗时(分钟) 实际耗时(分钟) Planning 计划 40 60 · Esti ...

  2. [译]在Javascript中进行日期相关的操作

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  3. C#中IDisposable的用法-垃圾回收

    在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...

  4. javascript 获取标签内的内容

    js 获取标签内的内容 参考:这篇博客给了我很大的启发. http://www.cnblogs.com/breakdown/archive/2012/10/09/2716221.html 我遇到的问题 ...

  5. Android下创建一个输入法

    输入法是一种可以让用户输入文字的控件.Android提供了一套可扩展的输入法框架,使得应用程序可以让用户选择各种类型的输入法,比如基于触屏的键盘输入或者基于语音.当安装了特定输入法之后,用户即可在系统 ...

  6. D - Back and Forth(模拟)

    Problem Statement Dolphin resides in two-dimensional Cartesian plane, with the positive x-axis point ...

  7. Springboot 实现前台动态配置数据源 (修改数据源之后自动重启)

    1.将 db.properties 存放在classpath路径; driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3 ...

  8. Golang 连接 MongoDB使用连接池

    可以免费试用 MongoDB ,500MB 平时做测试没有问题啦,连接数据库可能因为网络有点慢,但是我们是测试啊,不在乎这点吧~ 这是怎么申请试用版的博客,感谢这位大佬.注册好用起来很方便~ 传送门 ...

  9. DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)

    SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存 ...

  10. 教主的花园 dp

    题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢333种树,这3 ...