1 条题解
-
0
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5; int n, m, q, p[maxn], nxt[maxn], a[maxn], f[maxn][20], pos[maxn], g[maxn]; // nxt[x]表示排列中数值为x的数的下一个位置的数 // pos[x] 对于当前 a[i] 来说,a[i] 后面出现的数值为 x 的数里面的最小下标 a[j]==x 且 j 最小 int st[maxn][20]; // s[i][j] 表示 g[i] 开始的连续 2^j 个数的最小值 void build_st() { // 建立ST表 for (int j = 0; j <= 19; j++) { for (int i = 1; i+(1<<j)-1 <= m; i++) { if (j == 0) st[i][j] = g[i]; else st[i][j] = min(st[i][j-1], st[i+(1<<j-1)][j-1]); } } } int query_min(int l, int r) { // 查询 g[l..r] 的最小值 int len = log2(r - l + 1); return min(st[l][len], st[r-(1<<len)+1][len]); } int main() { scanf("%d%d%d", &n, &m, &q); for (int i = 0; i < n; i++) scanf("%d", p+i); for (int i = 0; i < n; i++) nxt[p[i]] = p[(i+1)%n]; for (int i = 1; i <= m; i++) scanf("%d", a+i); fill(pos+1, pos+n+1, m+1); // 把 pos[1..n] 都填充为 m+1 // f[m+1][0] = m+1; f[m+1][0..19] = m+1; fill(f[m+1], f[m+1]+20, m+1); for (int i = m; i >= 1; i--) { int x = nxt[a[i]]; // x : a[i] 在排列 p 中的下一个位置的数值 f[i][0] = pos[x]; pos[a[i]] = i; } for (int j = 1; j <= 19; j++) for (int i = 1; i <= m; i++) f[i][j] = f[f[i][j-1]][j-1]; for (int i = 1; i <= m; i++) { // 求 g[i] int u = i; for (int j = 0; j <= 19; j++) if (((n-1)>>j) & 1) u = f[u][j]; g[i] = u; } // for (int i = 1; i <= m; i++) // printf("g[%d] = %d\n", i, g[i]); build_st(); while (q--) { int l, r; scanf("%d%d", &l, &r); printf(query_min(l, r) <= r ? "1" : "0"); } return 0; }
- 1
信息
- ID
- 7
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 8
- 已通过
- 3
- 上传者