E. Lynyrd Skynyrd判断子列是否符合

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));
	}
}

猜你喜欢

转载自blog.csdn.net/qq_51945248/article/details/113733853