#include<cstdio> int n, m; intgcd(int a, int b){ return a ? gcd(b % a, a) : b; } intmain() { int T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); if (gcd(n, m) > 1) { puts("No"); continue; } puts("Yes"); int M = n * m; for (int i = 0; i < n; ++i) printf("%d ", (i * m + 1) % M); puts(""); for (int i = 0; i < m; ++i) printf("%d ", (i * n + 1) % M); puts(""); } return0; }
D
先不考虑修改,考虑交换的要求。不妨交换 A 序列,那么交换后一定是以 B 序列为参照更有序的。即可以合为一个序列,两者均对其修改,使得交换后的序列逆序对减少。注意到一次交换逆序对的奇偶性发生改变,最后逆序对数为 $0$ ,依此可以判断谁胜利。
再考虑修改,考虑修改对逆序对数的奇偶性的改变。注意到每一次修改都可以理解为 $r - l$ 次交换,那么左移 $k$ 次,即改变了 $k(r - l)$ 次奇偶性,与 A 或者 B 序列无关。
#include<cstdio> constint N = 5e5 + 10; constchar C[2] = { 'B', 'A' }; int n, tr[N]; voidadd(int x) { for (; x; x -= x & -x) tr[x] ^= 1; } boolquery(int x) { bool r = false; for (; x <= n; x += x & -x) r ^= tr[x]; return r; } boolread() { bool r = false; for (int i = 1, a; i <= n; ++i) { scanf("%d", &a); r ^= query(a); add(a); } for (int i = 1; i <= n; ++i) tr[i] = false; return r; } intmain() { int T; scanf("%d", &T); while (T--) { scanf("%d", &n); bool t = read() ^ read(); putchar(C[t]); for (int i = 1, l, r, k; i < n; ++i) { char c = getchar(); while (c != 'A' && c != 'B') c = getchar(); scanf("%d%d%d", &l, &r, &k); putchar(C[t ^= k & r - l & 1]); } puts(""); } return0; }
#include<cstdio> #include<vector> typedeflonglong L; constint N = 5e5 + 10; L h[N]; int n, m, q; bool f[N], in[N], vis[N]; int tp, stk[N]; int stmp, dfn[N], low[N], cnt, id[N]; int idx, hd[N], nxt[N], edg[N], wt[N]; std::vector <int> e[N]; voidadd(int a, int b, int c) { nxt[idx] = hd[a]; hd[a] = idx; edg[idx] = b; wt[idx++] = c; } voidchkmin(int &x, int k){ if (k < x) x = k; } boolchk(int u, L k) { if (vis[u]) return h[u] == k; vis[u] = true, h[u] = k; for (int i = hd[u], v = edg[i]; ~i; v = edg[i = nxt[i]]) if (id[u] == id[v] && !chk(v, k + wt[i])) returnfalse; returntrue; } voidtarjan(int u) { dfn[u] = low[u] = ++stmp; in[stk[++tp] = u] = true; for (int i = hd[u], v = edg[i]; ~i; v = edg[i = nxt[i]]) if (!dfn[v]) { tarjan(v); chkmin(low[u], low[v]); } elseif (in[v]) chkmin(low[u], dfn[v]); if (dfn[u] ^ low[u]) return; int v; do { in[v = stk[tp--]] = false; id[v] = cnt; } while (v ^ u); f[cnt++] = chk(u, 0) ^ 1; } booldfs(int u) { bool &r = f[u]; if (vis[u]) return r; vis[u] = true; for (int v : e[u]) r |= dfs(v); return r; } intmain() { scanf("%d%d%d", &n, &m, &q); for (int i = 0; i < n; ++i) hd[i] = -1; for (int a, b; m; --m) { scanf("%d%d", &a, &b); a = (a % n + n) % n; add(a, ((a + b) % n + n) % n, b); } for (int i = 0; i < n; ++i) vis[i] = false; for (int i = 0; i < n; ++i) id[i] = -1; for (int i = 0; i < n; ++i) if (!dfn[i]) tarjan(i); for (int u = 0; u < n; ++u) for (int i = hd[u], v = edg[i]; ~i; v = edg[i = nxt[i]]) if (id[u] ^ id[v]) e[id[u]].push_back(id[v]); for (int i = 0; i < n; ++i) vis[i] = false; for (int x; q; --q) { scanf("%d", &x); x = (x % n + n) % n; puts(dfs(id[x]) ? "Yes" : "No"); } return0; }