链接

https://codeforces.com/contest/213/problem/E

题目大意

给出两个排列a、b,长度分别为n、m,你需要计算有多少个x,使

得\(a_1 + x; a_2 + x; a_3 + x、、、 a_n + x\) 是b 的子序列(不连续的那种)。

思路

巧妙啊

暴力直接扫会T

我们构造一个c数组,使得c[b[i]]=i

这样x+1到x+1+n就是一段连续的区间了233

插回去看看他们相对大小是不是和a数组相同

因为不连续所以线段树维护hash值,线段树按照c数组的原路插回去

查询这一段是否hash值相同

؏؏☝ᖗ乛◡乛ᖘ☝؏؏

不知道双进制有没有用

update 19.3.14

写的稍微有点不清楚

因为a数组是个排列,所以[1,n]总的范围是1到n无重复

这样我们拿b数组开刀,c[b[i]]=i就是下标存值,值存下标。

这样你把他们放回去区间长度为n的下标,和a数组下标比较一下相对大小。

看看是否相同就可以判断是否是子串了。

然后[1,m],[2,m+1],[3,m+2]挨着扫就行了。

错误

报错:你数组开小啦

我:ull炸了吗?

代码

#include <iostream>
#include <cstdio>
#define ull unsigned long long
using namespace std;
const int N=2e5+7;
const int mod[2]={233,1000000009};
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,pos[N],a[N],b[N];
ull my_pow[2][N];
namespace seg {
#define ls rt<<1
#define rs rt<<1|1
struct node {
int siz;
ull tot[2];
}e[N<<2];
int cnt;
void pushup(int rt) {
e[rt].siz=e[ls].siz+e[rs].siz;
e[rt].tot[0]=(e[ls].tot[0]*my_pow[0][e[rs].siz+1]+e[rs].tot[0]);
e[rt].tot[1]=(e[ls].tot[1]*my_pow[1][e[rs].siz+1]+e[rs].tot[1]);
}
void update(int l,int r,int id,int k,int rt) {
if(l==r) {
if(k==-1) e[rt].siz=e[rt].tot[0]=e[rt].tot[1]=0;
else e[rt].siz=1,e[rt].tot[0]=e[rt].tot[1]=k;
return;
}
int mid=(l+r)>>1;
if(id<=mid) update(l,mid,id,k,ls);
else update(mid+1,r,id,k,rs);
pushup(rt);
}
}
int main() {
n=read(),m=read();
my_pow[1][1]=my_pow[0][1]=1;
for(int i=2;i<=n+1;++i) {
my_pow[0][i]=my_pow[0][i-1]*mod[0];
my_pow[1][i]=my_pow[1][i-1]*mod[1];
}
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=m;++i) b[i]=read();
ull hash[2]={0,0},tmp[2]={0,0};
for(int i=1;i<=n;++i) {
hash[0]=(hash[0]*mod[0]+a[i]);
hash[1]=(hash[1]*mod[1]+a[i]);
tmp[0]=(tmp[0]*mod[0]+1);
tmp[1]=(tmp[1]*mod[1]+1);
}
for(int i=1;i<=m;++i) pos[b[i]]=i;
int ans=0;
for(int i=1;i<=m;++i) {
if(i>n) seg::update(1,m,pos[i-n],-1,1);
seg::update(1,m,pos[i],i,1);
if(i>=n&&seg::e[1].tot[0]==(tmp[0]*(i-n)+hash[0])&&
seg::e[1].tot[1]==(tmp[1]*(i-n)+hash[1])) ans++;
}
cout<<ans<<"\n";
return 0;
}

cf213E 线段树维护hash的更多相关文章

  1. MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

    F - Permutation 思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个, 所以可以转换成,x+k, x-k在到x所在位置的时候是否 ...

  2. BZOJ 2124: 等差子序列 线段树维护hash

    2124: 等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列. Input 输入的第一行包含一 ...

  3. bzoj 2124 等差子序列 (线段树维护hash)

    2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 1922  Solved: 714[Submit][Status][Discuss ...

  4. Codeforces Round #321 (Div. 2) E Kefa and Watch (线段树维护Hash)

    E. Kefa and Watch time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  5. BZOJ 2124 线段树维护hash值

    思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了 ...

  6. 线段树 + 字符串Hash - Codeforces 580E Kefa and Watch

    Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是 ...

  7. cf580E. Kefa and Watch(线段树维护字符串hash)

    题意 $n$个数的序列,$m + k$种操作 1.$l , r, k$把$l - r$赋值为$k$ 2.$l, r, d$询问$l - r$是否有长度为$d$的循环节 Sol 首先有个神仙结论:若询问 ...

  8. CF213E Two Permutations 线段树维护哈希值

    当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$ 由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$; 如何判断呢?可以用哈希$qwq$: 我们用线段树维护哈 ...

  9. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

随机推荐

  1. python --- 字符编码学习小结

    上半年的KPI,是用python做一个测试桩系统,现在系统框架基本也差不多定下来了.里面有用到新学的工厂设计模式以及以及常用的大牛写框架的业务逻辑和python小技巧.发现之前自己写的代码还是面向过程 ...

  2. 软工网络15团队作业4——Alpha阶段敏捷冲刺3.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺3.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...

  3. multiprocessing 源码解析 更新中......

    一.参考链接 1.源码包下载·链接:   https://pypi.org/search/?q=multiprocessing+ 2.源码包 链接:https://pan.baidu.com/s/1j ...

  4. 20155228 2016-2017-2 《Java程序设计》第8周学习总结

    20155228 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 NIO与NIO2 NIO使用频道来衔接数据节点,在处理数据时,NIO可以让你设定缓冲区容量, ...

  5. Block 循环引用(中)

    不会造成循环引用的block 大部分GCD方法 dispatch_async(dispatch_get_main_queue(), ^{ [self doSomething]; }); 因为self并 ...

  6. maven项目没有src/test/java和src/test/resources目录问题解决

    新建maven项目,如下图示: 只有src/main/java和src/main/resources两个目录,而没有src/test/java和src/test/resources,于是第一反应是没有 ...

  7. VPS高性能虚拟机KVM详解

    1. KVM 介绍 1.0 虚拟化简史 其中,KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是Linux 的一个内核模块,该内核模块使得 Linux ...

  8. maven 项目打可执行jar包

    昨晚,突然就来了紧急任务. 验签较慢,着手优化,发来一个demo.     首先需要把该demo部署在Linux上.     该项目是maven 项目,所以用maven打个jar包,打完jar包之后, ...

  9. mysql-day06

    ##视图 - 什么是视图:在数据库中存在多种对象,表和视图都是数据库中的对象,创建视图时名称不能和表重名,视图实际上就代表一段sql查询语句,也可以理解成视图是一张虚拟的表,此虚拟表中的数据会随着原表 ...

  10. Caterpillar sis service information training and software

    Cat et sis caterpillar heavy duty truck diagnostics repair. Training demonstration allows.cat electr ...