E. Lynyrd Skynyrd
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Recently Lynyrd and Skynyrd went to a shop where Lynyrd bought a permutation p of length n, and Skynyrd bought an array a of length m, consisting of integers from 1 to n.
Lynyrd and Skynyrd became bored, so they asked you q queries, each of which has the following form: “does the subsegment of a from the l-th to the r-th positions, inclusive, have a subsequence that is a cyclic shift of p?” Please answer the queries.
A permutation of length n is a sequence of n integers such that each integer from 1 to n appears exactly once in it.
A cyclic shift of a permutation (p1,p2,…,pn) is a permutation (pi,pi+1,…,pn,p1,p2,…,pi−1) for some i from 1 to n. For example, a permutation (2,1,3) has three distinct cyclic shifts: (2,1,3), (1,3,2), (3,2,1).
A subsequence of a subsegment of array a from the l-th to the r-th positions, inclusive, is a sequence ai1,ai2,…,aik for some i1,i2,…,ik such that l≤i1<i2<…<ik≤r.
Input
The first line contains three integers n, m, q (1≤n,m,q≤2⋅105) — the length of the permutation p, the length of the array a and the number of queries.
The next line contains n integers from 1 to n, where the i-th of them is the i-th element of the permutation. Each integer from 1 to n appears exactly once.
The next line contains m integers from 1 to n, the i-th of them is the i-th element of the array a.
The next q lines describe queries. The i-th of these lines contains two integers li and ri (1≤li≤ri≤m), meaning that the i-th query is about the subsegment of the array from the li-th to the ri-th positions, inclusive.
Output
Print a single string of length q, consisting of 0 and 1, the digit on the i-th positions should be 1, if the subsegment of array a from the li-th to the ri-th positions, inclusive, contains a subsequence that is a cyclic shift of p, and 0 otherwise.
Examples
inputCopy
3 6 3
2 1 3
1 2 3 1 2 3
1 5
2 6
3 5
outputCopy
110
inputCopy
2 4 3
2 1
1 1 2 2
1 2
2 3
3 4
outputCopy
010
Note
In the first example the segment from the 1-st to the 5-th positions is 1,2,3,1,2. There is a subsequence 1,3,2 that is a cyclic shift of the permutation. The subsegment from the 2-nd to the 6-th positions also contains a subsequence 2,1,3 that is equal to the permutation. The subsegment from the 3-rd to the 5-th positions is 3,1,2, there is only one subsequence of length 3 (3,1,2), but it is not a cyclic shift of the permutation.
In the second example the possible cyclic shifts are 1,2 and 2,1. The subsegment from the 1-st to the 2-nd positions is 1,1, its subsequences are not cyclic shifts of the permutation. The subsegment from the 2-nd to the 3-rd positions is 1,2, it coincides with the permutation. The subsegment from the 3 to the 4 positions is 2,2, its subsequences are not cyclic shifts of the permutation.`
注释都在下面,看懂都还很困难,要注意实践
多个数组表示不同特性,用数组记录路径而不重叠更是出神入化
洛谷大佬SSerxhs的代码
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=2e5+2;
int p[N],a[N],lst[N],inxt[N],pre[N],c[N],dep[N],nd[N],r[N],lj[N],nxt[N],fir[N];
int n,m,q,i,j,cc,bs;
inline void add(int x,int y)//x:c[i],y:i
{//bs:计数器 ,等于y
lj[++bs]=y;//0 1 2 3 4 5 6 ...
nxt[bs]=fir[x];//nxt[i]=fir[c[i]],以c[i]为序号说在c中c[i]是第几个,i方便于fir指向,静态链表
fir[x]=bs;//fir[c[i]]=i,以c[i]为序号说在c中c[i]是第几个 ,时刻更新
}
inline void read(int &x)
{
cc=getchar();
while ((cc<48)||(cc>57)) cc=getchar();
x=cc^48;cc=getchar();
while ((cc>=48)&&(cc<=57))
{
x=x*10+(cc^48);
cc=getchar();
}
}
void dfs(int x)
{
int i;
nd[dep[x]]=x;//以dep[x]为序号,记录dep[x]在dep中的位置 ,留脚印
if (dep[x]>=n) //深度为n代表已经有所有的p了(一圈)
r[x]=nd[dep[x]-(n-1)];// nd:dep来时的位置;所以r[i]:至少要从j0=r[i]处来才行(最后问的是i,j)
else
r[x]=m+1;//r[i]要从j=m+1处来,不可能成功
for (i=fir[x];i;i=nxt[i])//管理c中所有可能路线 ,贪心,走一步看一步
{
dep[lj[i]]=dep[x]+1;//i未出界限,在m以内为m ;找下一个,找过的加1
dfs(lj[i]);
}
}
int main()
{
read(n);read(m);read(q);
for (i=1;i<=n;i++) {
read(p[i]);
inxt[p[i]]=p[i-1];
}
inxt[p[1]]=p[n];//inxt[p[i]]为p[i]的前一个
for (i=1;i<=m;i++)
{
read(a[i]);
pre[i]=lst[a[i]];//前一个与a[i]相同的数在哪里,以i为序号
lst[a[i]]=i;//记录a[i]的最后一次出现的位置 ,以a[i]为序号
for (j=lst[inxt[a[i]]];(j)&&(c[j]==0);j=pre[j]) {//j:i号3对应的a[i]3在p中的时候的前一个数1在a中从最后lst开始算出现的位置为i号1;让c[i]=后一个数出现的位置,知道这个后面有3号位的数,之后j=pre[j],对之前一个作用
c[j]=i;
}
}for (i=1;i<=m;i++)
if (!c[i])
c[i]=m+1;
for (i=1;i<=m;i++)
add(c[i],i);
dfs(m+1);
for (i=m-1;i;i--)
r[i]=min(r[i+1],r[i]);
while (q--)
{
read(i);
read(j);
putchar(48+(r[i]<=j));
}
}