[BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
题目链接:BZOJ - 3207
题目分析
先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x 。
这一步可以使用可持久化线段树来做,虽然感觉可以有更简单的做法,但是我没有什么想法...
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath> using namespace std; const int MaxN = 200000 + 5, P = 233, Mod = 3371723, MaxNode = 8000000 + 5; int n, m, k, en, TL_Index, Node_Index;
int A[MaxN], B[MaxN], Root[MaxN], Lc[MaxNode], Rc[MaxNode], T[MaxNode]; struct HashNode
{
int Pos, TL;
HashNode *Next;
} H[MaxN], *Ph = H, *Hash[Mod + 5]; bool Cmp(int *AA, int x, int *AB, int y) {
for (int i = 0; i < k; ++i)
if (AA[x + i] != AB[y + i]) return false;
return true;
} void Insert(int &Now, int Last, int s, int t, int x) {
if (Now == 0) Now = ++Node_Index;
if (s == t) {
T[Now] = T[Last] + 1;
return;
}
int m = (s + t) >> 1;
if (x <= m) {
Rc[Now] = Rc[Last];
Insert(Lc[Now], Lc[Last], s, m, x);
}
else {
Lc[Now] = Lc[Last];
Insert(Rc[Now], Rc[Last], m + 1, t, x);
}
} int main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
en = n - k + 1;
int HN, TL_i;
HashNode *Now;
TL_Index = 0;
Node_Index = 0;
for (int i = 1; i <= en; ++i) {
HN = 0;
for (int j = i; j < i + k; ++j) {
HN = HN * P + A[j];
if (HN > Mod) HN %= Mod;
}
Now = Hash[HN];
TL_i = 0;
while (Now != NULL) {
if (Cmp(A, i, A, Now -> Pos)) {
TL_i = Now -> TL;
break;
}
Now = Now -> Next;
}
if (TL_i == 0) {
++Ph; Ph -> Pos = i;
Ph -> TL = TL_i = ++TL_Index;
Ph -> Next = Hash[HN]; Hash[HN] = Ph;
}
Insert(Root[i], Root[i - 1], 1, n, TL_i);
}
int l, r, s, t, mid, x, y;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &l, &r);
for (int j = 1; j <= k; ++j) scanf("%d", &B[j]);
HN = 0;
for (int j = 1; j <= k; ++j) {
HN = HN * P + B[j];
if (HN > Mod) HN %= Mod;
}
TL_i = 0;
Now = Hash[HN];
while (Now != NULL) {
if (Cmp(B, 1, A, Now -> Pos)) {
TL_i = Now -> TL;
break;
}
Now = Now -> Next;
}
if (TL_i == 0 || r - l + 1 < k) printf("Yes\n");
else {
r = r - k + 1;
x = Root[l - 1]; y = Root[r];
s = 1; t = n;
while (s != t) {
mid = (s + t) >> 1;
if (TL_i <= mid) {
x = Lc[x]; y = Lc[y];
t = mid;
}
else {
x = Rc[x]; y = Rc[y];
s = mid + 1;
}
}
if (T[y] - T[x] > 0) printf("No\n");
else printf("Yes\n");
}
}
return 0;
}
[BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】的更多相关文章
- BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )
O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN) ----------------------------- ...
- 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队
看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...
- bzoj 3207 花神的嘲讽计划Ⅰ(哈希法+主席树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3207 [题意] 给定一个文本串,多次询问K长的模式串是否在文本[l,r]区间内出现. ...
- bzoj 3207 花神的嘲讽计划Ⅰ 主席树+hash
花神的嘲讽计划Ⅰ Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3112 Solved: 1086[Submit][Status][Discuss] ...
- bzoj 3207: 花神的嘲讽计划Ⅰ
Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: "哎你傻不傻的![hqz:大笨J]" "这道题又被J屎过了!!" "J这程序 ...
- BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...
- BZOJ 3207: 花神的嘲讽计划Ⅰ(莫队+哈希)
传送门 解题思路 刚开始写了个莫队+哈希+\(map\)的\(O(n\sqrt(n)log(n)\)的辣鸡做法,\(T\)飞了.后来看了看别人博客发现其实并不用拿\(map\)当桶存那些哈希值.因为只 ...
- BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树
BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树 Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程 ...
- 【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树
[BZOJ3207]花神的嘲讽计划Ⅰ Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快 ...
随机推荐
- ImageView 缩放
<ImageView android:id="@+id/imageview" android:layout_width="wrap_content" an ...
- POJ 1737 统计有n个顶点的连通图有多少个 (带标号)
设f(n)为所求答案 g(n)为n个顶点的非联通图 则f(n) + g(n) = h(n) = 2^(n * (n - 1) / 2) 其中h(n)是n个顶点的联图的个数 这样计算 先考虑1所在的连通 ...
- 【UVA】11732 - strcmp() Anyone?
一開始不知道这样的一维建树方法. 每次一层用一个链指向下一层最左边的结点,之后每一层用一个链表串联全部的结点,这样就建树成功了. 14328524 11732 option=com_onlinejud ...
- android 13 5种click事件不同实现方式 比较
第一种:不便于管理. <Button android:id="@+id/btn_Gridlayout" android:layout_width="match_pa ...
- 根据引用jar包路径查找原JAR包
网站:http://www.findjar.com/. 就是这个网站,经常在网上看到一些好的源码,什么都说了,就是没有说明需要引入那个包,这个包需要从什么地方下载,有些时候在网上搜索还不一定搜索得到, ...
- ubuntu 14.04 64位 下 编译安装MySQL 5.7.11
步骤一: 先去mysql的官方网站 去down 编译源码包 mysql 网址:www.mysql.com downloads (MySQL Community Server) 下载版本选择 sou ...
- js substr和substring字符串截取
substr(start,length)第一个参数是开始位置(注:start的开始是从0开始,看到好多博客上面是从1开始,在火狐和谷歌执行了一下是从0开始),第二个参数是截取字符串的长度(可以省略,表 ...
- Java_Activiti5_菜鸟也来学Activiti5工作流_之与Spring集成(三)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 解决UITableView中Cell重用机制导致内容出错的方法总结
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- Java反射学习(java reflect)(二)
ok之前说了Java的反射和反射分析类,那这些东西有神马作用呢,下面就来说应用: 三.运行时使用反射分析对象 简单写一个Employee类,然后利用JAVA反射去取name域,getDeclareFi ...