洛谷
假设区间\([l,r]\)内有一个循环位移,那么这个循环位移一定有一个最后的点,而这个点在循环位移中再往前移\(n-1\)个位置也一定在这个区间中。
那么我们将每一个点在它所在循环位移中前挪\(n-1\)个位置记下来,判断一下\([l,r]\)中是否有\(\geq l\)的点即可(具体实现详见代码)。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; inline int gi() { register int data = 0, w = 1; register char ch = 0; while (!isdigit(ch) && ch != '-') ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); return w * data; } const int MAX_N = 2e5 + 5; int N, M, Q; int a[MAX_N], p[MAX_N], tmp[MAX_N], nxt[18][MAX_N], pre[MAX_N]; int lg[MAX_N], st[18][MAX_N]; int query(int l, int r) { int t = lg[r - l + 1]; return max(st[t][l], st[t][r - (1 << t) + 1]); } int main () { #ifndef ONLINE_JUDGE freopen("cpp.in", "r", stdin); #endif N = gi(), M = gi(), Q = gi(); for (int i = 1; i <= N; i++) p[i] = gi(); p[0] = p[N]; for (int i = 1; i <= N; i++) pre[p[i]] = p[i - 1]; for (int i = 1; i <= M; i++) a[i] = gi(); for (int i = 1; i <= M; i++) nxt[0][i] = tmp[pre[a[i]]], tmp[a[i]] = i; for (int i = 2; i <= max(N, M); i++) lg[i] = lg[i >> 1] + 1; for (int i = 1; i <= lg[M]; i++) for (int j = 1; j <= M; j++) nxt[i][j] = nxt[i - 1][nxt[i - 1][j]]; for (int i = 1; i <= M; i++) { int pos = i; for (int j = 0; j <= lg[N - 1]; j++) if ((N - 1) >> j & 1) pos = nxt[j][pos]; st[0][i] = pos; } for (int i = 1; i <= lg[M]; i++) for (int j = 1; j + (1 << i) - 1 <= M; j++) st[i][j] = max(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]); while (Q--) { int l = gi(), r = gi(); if (query(l, r) >= l) putchar('1'); else putchar('0'); } putchar('\n'); return 0; }
====== 友链 ======
=== 同届的大佬 ===
x(m)gzc
water_mi
Longge
zzy
M_sea
ghost genius
ZTL
LS(CJ)lzf
zsbzsb
===== 学长们 =====
yyb
zsy
Itst
=== 外校的大佬 ===
tiger0132
hongzy
催更退役之后(
画饼大师 hyj
这个不是要加密码吗 qwq
催更 /se
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步