[序列自動機+倍增] 查詢是否存在一個給出的全排列的循環右移是給定區間的子序列 CF1143E

E. Lynyrd Skynyrd

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Recently Lynyrd and Skynyrd went to a shop where Lynyrd bought a permutation pp of length nn, and Skynyrd bought an array aa of length mm, consisting of integers from 11 to nn.

Lynyrd and Skynyrd became bored, so they asked you qq queries, each of which has the following form: "does the subsegment of aa from the ll-th to the rr-th positions, inclusive, have a subsequence that is a cyclic shift of pp?" Please answer the queries.

A permutation of length nn is a sequence of nn integers such that each integer from 11 to nn appears exactly once in it.

A cyclic shift of a permutation (p1,p2,…,pn)(p1,p2,…,pn) is a permutation (pi,pi+1,…,pn,p1,p2,…,pi−1)(pi,pi+1,…,pn,p1,p2,…,pi−1) for some ii from 11 to nn. For example, a permutation (2,1,3)(2,1,3) has three distinct cyclic shifts: (2,1,3)(2,1,3), (1,3,2)(1,3,2), (3,2,1)(3,2,1).

A subsequence of a subsegment of array aa from the ll-th to the rr-th positions, inclusive, is a sequence ai1,ai2,…,aikai1,ai2,…,aik for some i1,i2,…,iki1,i2,…,ik such that l≤i1<i2<…<ik≤rl≤i1<i2<…<ik≤r.

Input

The first line contains three integers nn, mm, qq (1≤n,m,q≤2⋅1051≤n,m,q≤2⋅105) — the length of the permutation pp, the length of the array aa and the number of queries.

The next line contains nn integers from 11 to nn, where the ii-th of them is the ii-th element of the permutation. Each integer from 11 to nnappears exactly once.

The next line contains mm integers from 11 to nn, the ii-th of them is the ii-th element of the array aa.

The next qq lines describe queries. The ii-th of these lines contains two integers lili and riri (1≤li≤ri≤m1≤li≤ri≤m), meaning that the ii-th query is about the subsegment of the array from the lili-th to the riri-th positions, inclusive.

Output

Print a single string of length qq, consisting of 00 and 11, the digit on the ii-th positions should be 11, if the subsegment of array aa from the lili-th to the riri-th positions, inclusive, contains a subsequence that is a cyclic shift of pp, and 00 otherwise.

Examples

input

Copy

3 6 3
2 1 3
1 2 3 1 2 3
1 5
2 6
3 5

output

Copy

110

input

Copy

2 4 3
2 1
1 1 2 2
1 2
2 3
3 4

output

Copy

010

Note

In the first example the segment from the 11-st to the 55-th positions is 1,2,3,1,21,2,3,1,2. There is a subsequence 1,3,21,3,2 that is a cyclic shift of the permutation. The subsegment from the 22-nd to the 66-th positions also contains a subsequence 2,1,32,1,3 that is equal to the permutation. The subsegment from the 33-rd to the 55-th positions is 3,1,23,1,2, there is only one subsequence of length 33 (3,1,23,1,2), but it is not a cyclic shift of the permutation.

In the second example the possible cyclic shifts are 1,21,2 and 2,12,1. The subsegment from the 11-st to the 22-nd positions is 1,11,1, its subsequences are not cyclic shifts of the permutation. The subsegment from the 22-nd to the 33-rd positions is 1,21,2, it coincides with the permutation. The subsegment from the 33 to the 44 positions is 2,22,2, its subsequences are not cyclic shifts of the permutation.

預處理每個字符的下一個字符是哪個. 最後一個字符的下一個是第一個字符.

從後往前遍歷a數組, 記錄當前字符的最近的下一個字符的位置(序列自動機)

下一個字符算作一步, 下兩個字符算作兩步, 倍增處理之後第n - 1個字符(組成長度爲n的排列)的位置, 記作lim[i];

每次詢問[L, R]時查詢區間內是否存在一個位置的lim <= R;

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int mn = 2e5 + 10;
const ll inf = 4e18;

int lim[4 * mn];
void update(int id, int l, int r, int num, int val)
{
	if (l == r)
	{
		lim[id] = val;
		return;
	}
	int mid = (l + r) >> 1;
	if (num <= mid)	update(2 * id, l, mid, num, val);
	else update(2 * id + 1, mid + 1, r, num, val);
	lim[id] = min(lim[2 * id], lim[2 * id + 1]);
}
int query(int id, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return lim[id];
	
	int mid = (l + r) >> 1;
	if (R <= mid)	
		return query(2 * id, l, mid, L, R);
	else if (L >= mid + 1)	
		return query(2 * id + 1, mid + 1, r, L, R);
	else 
		return min(query(2 * id, l, mid, L, mid), query(2 * id + 1, mid + 1, r, mid + 1, R));
}

int p[mn], a[mn], nx[mn], pos[mn], to[mn][30];
int main()
{
	int n, m, q;	scanf("%d %d %d", &n, &m, &q);
	for (int i = 1; i <= n; i++)	scanf("%d", &p[i]);
	for (int i = 1; i <= m; i++)	scanf("%d", &a[i]);
	
	// 每個字符的下一個
	for (int i = 1; i <= n - 1; i++)
		nx[p[i]] = p[i + 1];
	nx[p[n]] = p[1];
	
	for (int i = 1; i <= n; i++)
		pos[i] = m + 1;
	
	for (int i = 1; i <= m + 1; i++)
		for (int j = 0; j <= 20; j++)
		to[i][j] = m + 1;
		
	for (int i = m; i >= 1; i--)	// 序列自動機
	{
		to[i][0] = pos[nx[a[i]]];
		pos[a[i]] = i;
	}
	
	for (int j = 1; j <= 20; j++)	// 倍增
		for (int i = 1; i <= m; i++)
			to[i][j] = to[to[i][j - 1]][j - 1];
	
	for (int i = 0; i < 4 * m; i++)
		lim[i] = m + 1;
	for (int i = 1; i <= m; i++)
	{
		int ti = i, step = n - 1;
		for (int j = 20; j >= 0; j--)
		{
			if (to[ti][j] <= m && step - (1 << j) >= 0)
				ti = to[ti][j], step -= (1 << j);
		}
		update(1, 1, m, i, step == 0 ? ti : m + 1);
	}
	
	while (q--)
	{
		int l, r;	scanf("%d %d", &l, &r);
		int ans = query(1, 1, m, l, r);
		printf("%d", ans <= r ? 1 : 0);
	}
	
	return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章