BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=3207
给出一个长度为\(n\)的串,以及\(m\)个长度为\(k\)的串,求每个长度为\(k\)的串在原串\([x,y]\)区间是否出现过.
分析
这道题要求对比长度为\(k\)的串,于是我们把这些串的Hash值都算出来,问题就转化成了求\([x,y]\)的区间中是否出现过某Hash值.
求区间中某一个值出现了多少次,可以用主席树.
p.s.
1.学习了主席树指针的写法,比数组慢好多啊...看来有必要去学一学平衡树的数组写法...不过好处是不用自己算空间...
2.这道题自己算空间的话会MLE,所以卡着空间限制就好,估计数据比较小,可以过.
数组:
#include <bits/stdc++.h>
using namespace std; const int maxn=+,X=;
typedef unsigned long long ull;
const ull INF=~0ull;
int n,m,k,cnt;
int a[maxn],rt[maxn];
ull s[maxn],x=;
struct node{ int l,r,s; }t[maxn*];
inline int read(int &x){ x=;int k=;char c;for(c=getchar();c<''||c>'';c=getchar())if(c=='-')k=-;for(;c>=''&&c<='';c=getchar())x=x*+c-'';return x*=k; }
void update(ull l,ull r,int &pos,ull d){
t[++cnt]=t[pos]; pos=cnt; t[pos].s++;
if(l==r) return;
ull mid=l+(r-l)/;
if(d<=mid) update(l,mid,t[pos].l,d);
else update(mid+,r,t[pos].r,d);
}
bool query(int x,int y,ull l,ull r,ull d){
if(t[y].s-t[x].s==) return false;
if(l==r) return true;
ull mid=l+(r-l)/;
if(d<=mid) return query(t[x].l,t[y].l,l,mid,d);
else return query(t[x].r,t[y].r,mid+,r,d);
}
int main(){
read(n); read(m); read(k);
for(int i=;i<=n;i++){
read(a[i]);
s[i]=s[i-]*X+(ull)a[i];
}
for(int i=;i<=k;i++) x*=X;
for(int i=k;i<=n;i++) rt[i]=rt[i-], update(0ull,INF,rt[i],s[i]-s[i-k]*x);
for(int i=;i<=m;i++){
ull hash=; bool ans;
int l,r; read(l); read(r);
for(int j=,t;j<=k;j++) hash=hash*X+read(t);
if(r+-l<k) ans=false;
else ans=query(rt[l+k-],rt[r],0ull,INF,hash);
ans?puts("No"):puts("Yes");
}
return ;
}
指针:
#include <bits/stdc++.h>
using namespace std; const int maxn=+,X=;
typedef unsigned long long ull;
const ull INF=~0ull;
int n,m,k,cnt;
int a[maxn];
ull s[maxn],x=;
struct node{
node* l,* r; int s;
node(){}
node(node *l,node* r,int s):l(l),r(r),s(s){}
}* rt[maxn],* null;
inline int read(int &x){ x=;int k=;char c;for(c=getchar();c<''||c>'';c=getchar())if(c=='-')k=-;for(;c>=''&&c<='';c=getchar())x=x*+c-'';return x*=k; }
node* update(node* t,ull l,ull r,ull d){
if(l==r) return new node(null,null,t->s+);
ull mid=l+(r-l)/;
if(d<=mid) return new node(update(t->l,l,mid,d),t->r,t->s+);
else return new node(t->l,update(t->r,mid+,r,d),t->s+);
}
bool query(node* x,node* y,ull l,ull r,ull d){
if(y->s-x->s==) return false;
if(l==r) return true;
ull mid=l+(r-l)/;
if(d<=mid) return query(x->l,y->l,l,mid,d);
else return query(x->r,y->r,mid+,r,d);
}
int main(){
read(n); read(m); read(k);
null=new node;
null->l=null, null->r=null, null->s=;
for(int i=;i<=n;i++){
read(a[i]);
s[i]=s[i-]*X+(ull)a[i];
}
for(int i=;i<=k;i++) x*=X;
rt[k-]=new node(null,null,);
for(int i=k;i<=n;i++) rt[i]=update(rt[i-],0ull,INF,s[i]-s[i-k]*x);
for(int i=;i<=m;i++){
ull hash=; bool ans;
int l,r; read(l); read(r);
for(int j=,t;j<=k;j++) hash=hash*X+read(t);
if(r+-l<k) ans=false;
else ans=query(rt[l+k-],rt[r],0ull,INF,hash);
ans?puts("No"):puts("Yes");
}
return ;
}
BZOJ_3207_花神的嘲讽计划1_(Hash+主席树)的更多相关文章
- BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树
BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树 Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程 ...
- BZOJ3207: 花神的嘲讽计划Ⅰ(hash)
3207: 花神的嘲讽计划Ⅰ Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3569 Solved: 1258[Submit][Status][Di ...
- [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...
- [bzoj3207]花神的嘲讽计划Ⅰ[可持久化线段树,hash]
将每k个数字求一个哈希值,存入可持久化线段树,直接查询即可 #include <iostream> #include <algorithm> #include <cstd ...
- BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...
- 【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树
[BZOJ3207]花神的嘲讽计划Ⅰ Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快 ...
- bzoj 3207 花神的嘲讽计划Ⅰ 主席树+hash
花神的嘲讽计划Ⅰ Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3112 Solved: 1086[Submit][Status][Discuss] ...
- BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )
O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN) ----------------------------- ...
- 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队
看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...
随机推荐
- Web前端新人笔记之HeightCharts基础
通常情况下,Highcharts包含标题(Title).坐标轴(Axis).数据列(Series).数据提示框(Tooltip).图例(Legend).版权信息(Credits)等,高级的还包括导出功 ...
- C++ GUI Programming with Qt4 笔记 -- chap2 QDialog
以 finddialog 为例,介绍 QDialog.并对 Qt 的基本概念和技巧做了更进一步(chap1)的介绍. 1.MOC 扩展与signals–slots 机制 严格来说,Qt 开发,写的并不 ...
- Linux C 程序 基础语法(1)
1.Linux 下第一支C程序,控制台打印一句话. vi first.c //linux新建文件 #include<stdio.h> int main() { printf("w ...
- 【分享】 高级Visual Basic 编程 清晰pdf+随书源代码光盘
搞vb6的可能不多,博客园也大多是.net java,近日在网上找到这本好书,想要成为vb高手,这本书不要错过,学完你会发现win32下,vb6还真是无所不能.可贵的是本书的作者是当时vb6 IDE的 ...
- 特殊的Python
在学习python之前,我也学习过C ,C++ ,Java ,PHP ,javascript,前端也学习过.但是在学习Python的这段时间里,多多少少也感觉到Python在语法方面的不同和特殊性. ...
- 调试NodeJS应用
OS:Windows 1.下载安装NodeJS 点击http://nodejs.org/界面上“Install”,下载后运行安装,默认安装到到C:\Program Files\nodejs.安装后确认 ...
- Stop a hung service 关闭一个无响应的windows 服务
If you ever have trouble with a service being stuck in a 'starting' or 'stopping' state, you can run ...
- C99标准中的部分新特性
我有点怀疑我会不会C语言了. 1.变长数组(VLA) ; scanf("%d", &n); int arr[n]; 2.数组初始化 ] = {[] = , [] = , [ ...
- Get your Windows product key from a script
The product key is located in the registry under HKLM\Software\Microsoft\Windows NT\CurrentVersion I ...
- iOS上绘制自然的签名-b
这里有一篇很棒的文章写如何在Android上获取流畅的签名:Smoother Signatures:https://corner.squareup.com/2012/07/smoother-signa ...