Link

有两种做法:

第一种是\(O(nlog\ n)\)的。

我们预处理两个数组:

\(pre_i\)表示\(p\)中\(i\)前面的那个数是\(pre_i\)。

\(lst_i\)表示\(a\)中\(a_i\)前一个\(pre_{a_i}\)的位置。(代码中是\(f_0\))

那么每个数往前跳几次\(lst\),也就会对应排列\(p\)中的一段连续子串。

然后处理往前跳\(lst\)的倍增数组。

我们知道,\(p\)是一个循环排列,所以对于每个数,以这个数结束的最短的是\(p\)的循环移位的\(a\)的子序列,就是从这个数往前跳\(n-1\)次\(lst\)得到的子序列。

所以我们处理出每个点往前跳\(n-1\)次\(lst\)得到的位置\(edp\)。

对于一次询问\(l,r\),如果\(l,r\)中存在子序列为\(p\)的循环移位,那么就会满足\(\exist i\in[l,r],edp_i\in[l,r]\)。

所以我们用\(st\)表维护区间最小值即可。

#include<bits/stdc++.h>
using namespace std;
const int N=200007;
int p[N],a[N],f[21][N],pre[N],lst[N],Log[N],st[21][N];
int max(int a,int b){return a>b? a:b;}
int read(){int x;scanf("%d",&x);return x;}
int get(int l,int r){int k=Log[r-l+1];return max(st[k][l],st[k][r-(1<<k)+1]);}
int main()
{
int n=read(),m=read(),q=read(),i,j,l,r;
for(i=1;i<=n;++i) p[i]=read();
p[0]=p[n];
for(i=1;i<=n;++i) pre[p[i]]=p[i-1];
for(i=1;i<=m;++i) a[i]=read();
for(i=1;i<=m;++i) f[0][i]=lst[pre[a[i]]],lst[a[i]]=i;
for(i=2;i<=n||i<=m;++i) Log[i]=Log[i>>1]+1;
for(i=1;i<=Log[n];++i) for(j=1;j<=m;++j) f[i][j]=f[i-1][f[i-1][j]];
for(i=1;i<=m;++i) for(st[j=0][i]=i;j<=Log[n-1];++j) if((n-1)&(1<<j)) st[0][i]=f[j][st[0][i]];
for(i=1;i<=Log[m];++i) for(j=1;j+(1<<i)-1<=m;++j) st[i][j]=max(st[i-1][j],st[i-1][j+(1<<i-1)]);
while(q--) l=read(),r=read(),putchar(get(l,r)>=l? '1':'0');
}

第二种是\(O(n)\)的。

我们处理两个数组:

\(ppre_i\)表示\(p\)中\(i\)前面的那个数是\(ppre_i\)。

\(apre_i\)表示\(a\)中前一个\(a_i\)的位置。

然后从前往后扫\(a\)数组,把\(a_i\)前面所有未连边的\(ppre_{a_i}\)的位置向\(i\)连边,并且打上标记,下次不再连边。

那么我们知道每个点最多只有一个入边。没有入边的,我们新建一个\(0\)到这个点的边。

总的,我们会建出一棵树。

\(a\)数组中\(a_i\)向前跳一次\(lst\)(上面那个做法的跳)也就是跳一次父亲。

所以上面做法的跳\(n-1\)次就变成了\(n-1\)级祖先。

考虑dfs的过程,dfs到某个点经过的点(也就是dfs的栈)存的都是根到当前节点的路径。

所以每个节点dfs到时(进栈)把当前深度的节点(\(b\)数组)记为自己,因此\(n-1\)级祖先就是\(b[dep[u]-(n-1)]\)。

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=200007;
int n,m,q,p[N],a[N],apre[N],lst[N],ppre[N],fa[N],dep[N],w[N],b[N];
vector<int>G[N];
int max(int a,int b){return a>b? a:b;}
int min(int a,int b){return a<b? a:b;}
int read(){int x;scanf("%d",&x);return x;}
void dfs(int u)
{
int i,v;
b[dep[u]]=u,w[u]=dep[u]>=n? b[dep[u]-(n-1)]:m+1;
for(i=G[u].size()-1;~i;--i) v=G[u][i],dep[v]=dep[u]+1,dfs(v);
}
int main()
{
n=read(),m=read(),q=read();int i,j;
for(i=1;i<=n;++i) p[i]=read();
p[0]=p[n];
for(i=1;i<=n;++i) ppre[p[i]]=p[i-1];
for(i=1;i<=m;++i)
{
a[i]=read(),apre[i]=lst[a[i]],lst[a[i]]=i;
for(j=lst[ppre[a[i]]];j&&!fa[j];j=apre[j]) fa[j]=i;
}
for(i=1;i<=m;++i) fa[i]? G[fa[i]].pb(i):G[0].pb(i);
dfs(0);
for(i=m-1;i;--i) w[i]=min(w[i+1],w[i]);
while(q--) i=read(),j=read(),putchar(48+(w[i]<=j));
}

CF1142B Lynyrd Skynyrd的更多相关文章

  1. 【题解】CF1142B Lynyrd Skynyrd(倍增)

    [题解]CF1142B Lynyrd Skynyrd(倍增) 调了一个小时原来是读入读反了.... 求子段是否存在一个排列的子序列的套路是把给定排列看做置换,然后让给定的序列乘上这个置换,问题就转化为 ...

  2. 【CF1142B】Lynyrd Skynyrd

    [CF1142B]Lynyrd Skynyrd 题面 洛谷 题解 假设区间\([l,r]\)内有一个循环位移,那么这个循环位移一定有一个最后的点,而这个点在循环位移中再往前移\(n-1\)个位置也一定 ...

  3. CF1142E/1143B Lynyrd Skynyrd

    CF1142E/1143B Lynyrd Skynyrd 开始读错题了,以为是连续的一段,敲完后才发现是 \(subsequence\) ... 考虑对于 \(a\) 中的每个 \(a_i\) 找到它 ...

  4. 「CF1142B」Lynyrd Skynyrd

    传送门 Luogu 解题思路 发现一个性质: 对于排列的任何一个循环位移,排列中的同一个数的前驱肯定是不变的. 而且,如果一个排列的循环位移是某一个区间的子序列,那么这个循环位移的结尾的 \(n-1\ ...

  5. 『题解』Codeforces1142B Lynyrd Skynyrd

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description Recently Lynyrd and Skynyrd went to a ...

  6. B. Lynyrd Skynyrd

    传送门: 题意:给出 n,m,q 然后给出模板串,从1-n数字只出现一次,然后给出长度为m的要询问的串. q组询问:每组询问输出 ‘1’或者‘0’ 每组询问 一对x,y    问在x到y中有没有模板串 ...

  7. Codeforces 1142B Lynyrd Skynyrd

    ---恢复内容开始--- 题意:给你一个排列p和数组a,有t组询问,每次询问一个区间的子序列中是否有p的一个循环排列. 思路:以p = [3, 1, 2]举例, 我们扫描数组b,假设当前数字是1,那么 ...

  8. Codeforces Round #549 (Div. 1)

    今天试图用typora写题解 真开心 参考 你会发现有很多都是参考的..zblzbl Codeforces Round #549 (Div. 1) 最近脑子不行啦 需要cf来缓解一下 A. The B ...

  9. Codeforces Round #549 (Div. 2) 训练实录 (5/6)

    The Doors +0 找出输入的01数列里,0或者1先出完的的下标. Nirvana +3 输入n,求1到n的数字,哪个数逐位相乘的积最大,输出最大积. 思路是按位比较,从低到高,依次把小位换成全 ...

随机推荐

  1. Clojure的引用类型:var,ref,agent和atom

    作为其他值的容器,也都可以解引用. deref不会阻塞. add-watch (add-watch reference key fn) 可以定义引用值发生改变时的回调,fn是4个参数 :key (at ...

  2. HGOI20190706 题解

    Problem A 质因数 设f(x) 表示x的不同质因子个数,给出T组x,询问f(x)的值. 对于100%的数据 $x,T \leq 10^5 $ Sol : 第一遍欧拉筛,并记录下每个数的最小质因 ...

  3. Android_(游戏)打飞机04:绘画敌机、添加子弹

    (游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹   传送门 (游戏)打飞机05:处理子弹, ...

  4. sqli-libs(3)

    今天我们来讲解 sqli-libs(3) 有括号的单引号报错  首先我们来查看加入'看报错了 在加‘’ 没报错 证明 存在注入 然后我们看加入’的报错回显的是什么 和我们的sqli-libs(1)的报 ...

  5. RedisTemplate 用法

      Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有 ...

  6. 利用angular4和nodejs-express构建一个简单的网站(五)—用户的注册和登录-HttpClient

    上一节简单介绍了一下利用angular构建的主路由模块,根据上一节的介绍,主页面加载时直接跳转到用户管理界面,下面就来介绍一下用户管理模块.启动应用后,初始界面应该是这样的: 用户管理模块(users ...

  7. 可滚动UIStackView 竖向居中 / 横向右对齐

    重点: 在scroll view和stack view之间加一个UIView. 竖向居中Tutorial: https://stackoverflow.com/questions/50766400/c ...

  8. Android Studio在Make Project时下载Grandle特别慢

    SDK下载完成了,建个工程, 又蒙了: Server returned HTTP response code: 502 for URL: https://services.gradle.org/dis ...

  9. 问题:unknown error: call function result missing 'value' 解决方法

    问题:unknown error: call function result missing 'value' 页面也没有 填充信息 原因是:安装与chrome和对应的chromedriver版本问题 ...

  10. jenkins与docker(DevOps二)

    Jenkins官网 https://jenkins.io/download/ centos 7安装Docker https://www.cnblogs.com/stulzq/p/7743073.htm ...