Rubik is very keen on number permutations.

A permutation a with length n is a sequence, consisting of n different numbers from 1 to n. Element number i (1 ≤ i ≤ n) of this permutation will be denoted as ai.

Furik decided to make a present to Rubik and came up with a new problem on permutations. Furik tells Rubik two number permutations: permutation a with length n and permutation b with length m. Rubik must give an answer to the problem: how many distinct integers d exist, such that sequence c (c1 = a1 + d, c2 = a2 + d, ..., cn = an + d) of length n is a subsequence of b.

Sequence a is a subsequence of sequence b, if there are such indices i1, i2, ..., in(1 ≤ i1 < i2 < ... < in ≤ m), that a1 = bi1a2 = bi2, ..., an = bin, where n is the length of sequence a, and m is the length of sequence b.

You are given permutations a and b, help Rubik solve the given problem.

Input

The first line contains two integers n and m (1 ≤ n ≤ m ≤ 200000) — the sizes of the given permutations. The second line contains n distinct integers — permutation a, the third line contains m distinct integers — permutation b. Numbers on the lines are separated by spaces.

Output

On a single line print the answer to the problem.

Example

Input
1 1
1
1
Output
1
Input
1 2
1
2 1
Output
2
Input
3 3
2 3 1
1 2 3
Output
0

题意:给定全排列A(1-N),全排列B(1-M),问有多少个d,满足全排列A的每一位+d后,是B的子序列(不是字串)。

思路:对于全排列A,得到hashA,先在B中得到1-N的hashB。每次d++的新排列,等效于1到N+1的排列每一位减去1(hash实现)。

具体的代码一看就明白。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const int maxn=;
const int B=;
int N,M,pos[maxn],x;
ull g[maxn];
ull val,sum;
struct SegmentTree
{
ull hash[maxn<<];
int cnt[maxn<<];
void build(int Now,int l,int r)
{
hash[Now]=cnt[Now]=;
if(l==r) return ;
int mid=(l+r)>>;
build(Now<<,l,mid);
build(Now<<|,mid+,r);
}
void pushup(int Now)
{
hash[Now]=hash[Now<<]*g[cnt[Now<<|]]+hash[Now<<|];
cnt[Now]=cnt[Now<<]+cnt[Now<<|];
}
void update(int Now,int l,int r,int pos,int val,int num)
{
if(l==r)
{
hash[Now]+=num*val;
cnt[Now]+=num;
return;
}
int mid=(l+r)>>;
if(pos<=mid) update(Now<<,l,mid,pos,val,num);
else update(Now<<|,mid+,r,pos,val,num);
pushup(Now);
}
}Tree;
int main()
{
while(~scanf("%d%d",&N,&M))
{
val=sum=;
g[]=;
for(int i=;i<=N;i++) g[i]=g[i-]*B, sum+=g[i-];
for(int i=;i<=N;i++){
scanf("%d",&x);
val=val*B+x;
}
for(int i=;i<=M;i++){
scanf("%d",&x);
pos[x]=i;
}
Tree.build(,,M);
int ans=;
for(int i=;i<=M;i++)//把数值1~M按顺序加入线段树中
{
Tree.update(,,M,pos[i],i,);
if(i>=N)
{
if(Tree.hash[]-(sum*(i-N))==val) ans++;
Tree.update(,,M,pos[i-N+],i-N+,-);
}
}
printf("%d\n",ans);
}
return ;
}

最新文章

  1. Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager
  2. Linux 下 JAVA 安装及配置
  3. java对过反射调用方法
  4. C++中的多态与虚函数的内部实现
  5. Jquery Validate 正则表达式实用验证代码
  6. 我的R代码备份
  7. css 包含的图片和style=&quot;display:none&quot;可以避免图片加载,可以节省网络流量
  8. Android环境配置Sencha Touch
  9. ListBox基础
  10. 青云QingCloud业内率先支持云端全面透明代理功能 | SDNLAB | 专注网络创新技术
  11. codevs2492 上帝造题的七分钟 2
  12. solr error logs org.apache.solr.common.SolrException: ERROR: [doc=17] unknown field alias
  13. asp.net webForm 前后台类关系
  14. sqlserver 批量删除相同前缀名的表
  15. 解决新建maven项目速度慢的问题
  16. Description has only two Sentences(欧拉定理 +快速幂+分解质因数)
  17. fs-max、file-nr和nofile的关系
  18. 理解Java注解类型
  19. css overflow和float
  20. Android学习总结——输入法将BottomNavigationBar(底部导航栏)顶上去的问题

热门文章

  1. XV6调度
  2. HDU1686 计算模式串匹配的次数
  3. ArrayList去除重复元素
  4. transient 关键字
  5. Linux下使用Curl调用Java的WebService接口
  6. mysql查询今天,昨天,近7天,近30天,本月,上一月数据的SQL
  7. zookeeper客户端
  8. 九度OJ1004 Median
  9. Visual Studio Visual assistant注释也做拼写检查怎么办
  10. C++对象模型——解构语意学(第五章)