描述


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+主席树)的更多相关文章

  1. BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树

    BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树 Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程 ...

  2. BZOJ3207: 花神的嘲讽计划Ⅰ(hash)

    3207: 花神的嘲讽计划Ⅰ Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3569  Solved: 1258[Submit][Status][Di ...

  3. [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】

    题目链接:BZOJ - 3207 题目分析 先使用Hash,把每个长度为 k 的序列转为一个整数,然后题目就转化为了询问某个区间内有没有整数 x . 这一步可以使用可持久化线段树来做,虽然感觉可以有更 ...

  4. [bzoj3207]花神的嘲讽计划Ⅰ[可持久化线段树,hash]

    将每k个数字求一个哈希值,存入可持久化线段树,直接查询即可 #include <iostream> #include <algorithm> #include <cstd ...

  5. BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...

  6. 【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树

    [BZOJ3207]花神的嘲讽计划Ⅰ Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快 ...

  7. bzoj 3207 花神的嘲讽计划Ⅰ 主席树+hash

    花神的嘲讽计划Ⅰ Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3112  Solved: 1086[Submit][Status][Discuss] ...

  8. BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )

    O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN) ----------------------------- ...

  9. 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队

    看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...

随机推荐

  1. bzoj4637:期望

    思路:最小生成树计数只不过加了一个期望,由于期望具有线性性质,就可以转化为每条边的期望之和,那么一条边的期望如何求呢,在最小生成树记数中,是把相同边权的一起处理,之后把属于连通块内的点缩点,也就是说, ...

  2. MFC GDI相关对象

    首先说明几个名词: CDC 是MFC对Wind32 API的设备上下文(DC)进行封装的C++类,由他继承的类包括 CPaintDC(常用)CWindowDC(现在软件基本不用) CClientDC( ...

  3. dialog的传值

    A页面 等待B页面返回值的textBox:<asp:TextBox ID="TextBox1" runat="server"></asp:Te ...

  4. 使用json方式实现省市两级下拉级联菜单[原创]

    本文为博主原创,转载请注明. 首先看一下实现后的效果图: 当然,要完成这个实验,mysql必须与数据库连接,这里选用navicat for mysql这款软件,它与mysql的契合度是很高的,配置环境 ...

  5. java.util.regx Demo

    import java.util.regex.Matcher;import java.util.regex.Pattern; public class TestRegex { public stati ...

  6. starling 中 的特效

    一. 最好用同一张图片进行缩放变形等处理后组合,这样可以每帧一draw

  7. linux定时执行php脚本

    1.查看lynx命令所在的路径 whereis lynx 或者 which lynx 如果没有,则安装 yum install lynx 或者 apt-get方式(ubuntu) 2.建立 shell ...

  8. aspx页面状态管理Cookie和ViewState

    Cookie 设置cookie protected void Button2_Click(object sender, EventArgs e) { HttpCookie cookie = new H ...

  9. ACE 6.2.0 RHEL6_Linux 编译

    第一步. 设置环境变量 export ACE_ROOT=$HOME/ace/ACE_wrappersexport LD_LIBRARY_PATH=$ACE_ROOT/ace:$ACE_ROOT/lib ...

  10. vb delphi7、2010 csharp vb.net空白测试程序

    工作中难免在网上看到一段不错的代码,希望能够拿来测试一次,为了避免每次测试都要新建一个空白测试程序,索性预先建立好,要用的时候复制一遍,然后打开直接粘贴需要测试的代码进行测试.