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