比赛链接

点击打开链接

官方题解

点击打开链接

Problem A. Mind Control

不难发现玩家可以选择到的两个权值仅与之前玩家选择开头元素的次数 iii 有关。

因此,枚举强制之前玩家选择开头元素的次数,最坏的情况就是对应区间里最小的权值。

时间复杂度 O(N2)O(N^2)O(N2) 。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
int a[MAXN], b[MAXN];
int main() {int T; read(T);while (T--) {int n, m, k;read(n), read(m), read(k);chkmin(k, m - 1);for (int i = 1; i <= n; i++)read(a[i]);for (int i = 0, j = n - m + 1; i <= m - 1; i++, j++)b[i] = max(a[i + 1], a[j]);int ans = 0;for (int i = 0, j = m - k - 1; j <= m - 1; i++, j++) {int Min = 2e9;for (int l = i; l <= j; l++)chkmin(Min, b[l]);chkmax(ans, Min);}cout << ans << endl;}return 0;
}

Problem B. Irreducible Anagrams

当 l=rl=rl=r 时答案显然为 Yes 。

若 sl≠srs_l\ne s_rsl​​=sr​ ,可以考虑将所有 sls_lsl​ 排列在最右侧, srs_rsr​ 排列在最左侧,其余字符任意排列,可以证明得到的字符串一定符合条件,因此答案为 Yes 。

否则,即 sl=srs_l=s_rsl​=sr​ ,若区间内字符种类数在 222 以内,答案为 No ,种类数为 111 时显然,种类数为 222 时可以通过将字符看做 +1,−1+1,-1+1,−1 ,作折线图证明。

否则,将 sls_lsl​ 排列在中间,某两种字符排在两边,可以证明,在交换字符种类的排列顺序后,同样可以得到一个合法的构造,因此答案为 Yes 。

时间复杂度 O(∣S∣+Q)O(|S|+Q)O(∣S∣+Q) 。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
char s[MAXN];
int sum[MAXN][26];
int main() {scanf("%s", s + 1);int n = strlen(s + 1);for (int i = 1; i <= n; i++)for (int j = 0; j <= 25; j++)sum[i][j] = sum[i - 1][j] + (s[i] - 'a' == j);int q; read(q);while (q--) {int l, r; read(l), read(r);if (l == r || s[l] != s[r]) puts("Yes");else {int cnt = 0;for (int i = 0; i <= 25; i++)cnt += (sum[r][i] - sum[l - 1][i]) != 0;if (cnt >= 3) puts("Yes");else puts("No");}}return 0;
}

Problem C. Prefix Enlightenment

将各个集合选或不选看做事件,则各个元素的限制应当形如:
(1)(1)(1) 、某个集合必须选或不选
(2)(2)(2) 、某两个集合的选取状态必须相同或不同

将各个事件是否成立拆点,并查集即可。

时间复杂度 O(N+K)O(N+K)O(N+K) 。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 6e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
template <typename T> void write(T x) {if (x < 0) x = -x, putchar('-');if (x > 9) write(x / 10);putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {write(x);puts("");
}
int tr, fl, ans, f[MAXN], s[MAXN][2];
int find(int x) {if (f[x] == x) return x;else return f[x] = find(f[x]);
}
char st[MAXN];
vector <int> a[MAXN];
int calc(int x) {x = find(x);if (x == tr) return s[x][1];if (x == fl) return s[x][0];return min(s[x][1], s[x][0]);
}
void merge(int x, int y) {if (find(x) == find(y)) return;x = find(x), y = find(y);if (x > y) swap(x, y);f[x] = y, s[y][0] += s[x][0], s[y][1] += s[x][1];
}
int main() {int n, m; read(n), read(m);scanf("\n%s", st + 1);for (int i = 1; i <= m; i++) {int x; read(x);while (x--) {int y; read(y);a[y].push_back(i);}}for (int i = 1; i <= m; i++) {f[i] = i, f[i + m] = i + m;s[i][0] = 1, s[i + m][1] = 1;}tr = m * 2 + 1, fl = m * 2 + 2, ans = 0;f[tr] = tr, f[fl] = fl;for (int i = 1; i <= n; i++) {int x, y;if (a[i].size() != 0) {if (st[i] == '0') {if (a[i].size() == 1) {int x = a[i][0];if (find(x + m) != find(tr)) {ans -= calc(x + m);ans -= calc(tr);merge(x + m, tr);merge(x, fl);ans += calc(x + m);}} else {int x = a[i][0], y = a[i][1];if (find(x) != find(y + m)) {ans -= calc(x);ans -= calc(y);merge(x + m, y);merge(x, y + m);ans += calc(x);}}} else {if (a[i].size() == 1) {int x = a[i][0];if (find(x) != find(tr)) {ans -= calc(x);ans -= calc(tr);merge(x, tr);merge(x + m, fl);ans += calc(x);}} else {int x = a[i][0], y = a[i][1];if (find(x) != find(y)) {ans -= calc(x);ans -= calc(y);merge(x, y);merge(x + m, y + m);ans += calc(x);}}}}printf("%d\n", ans);}return 0;
}

Problem D. Coffee Varieties (hard version)

单独考虑 K=1K=1K=1 的情况。

对于一般的情况,我们希望求出每个元素之前是否出现过。

将相邻的 K2\frac{K}{2}2K​ 个元素分为一组,按照顺序操作两组元素可以检测后一组的每个元素是否在前一组中出现,因此,我们希望将组与组之间串成若干条链,使得每两组均在某条链上相邻。

则贪心串链即可,贪心的方式可见代码。

时间复杂度 O(N2K)O(\frac{N^2}{K})O(KN2​) ,操作次数在 3N22K\frac{3N^2}{2K}2K3N2​ 以内。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
bool ans[MAXN];
vector <int> a[MAXN], b[MAXN], c[MAXN];
int main() {int n, k; read(n), read(k);if (k == 1) {int ans = 0;for (int i = 1; i <= n; i++) {bool res = true;for (int j = 1; j <= i - 1; j++) {char c;cout << '?' << ' ' << i << endl;scanf("\n%c", &c);cout << '?' << ' ' << j << endl;scanf("\n%c", &c);cout << 'R' << endl;if (c == 'Y') res = false;}ans += res;}cout << '!' << ' ' << ans << endl;} else {for (int i = 1; i <= n; i++)ans[i] = true;int m = n / (k / 2);for (int i = 1, j = 1; i <= m; i++, j += k / 2)for (int l = 1; l <= k / 2; l++)a[i].push_back(j + l - 1);int cnt = 0;for (int i = 1; i <= m; i++)for (int j = 1; j <= i - 1; j++) {if (b[j].size()) {int tmp = b[j].back();b[j].pop_back();c[tmp].push_back(i);b[i].push_back(tmp);} else {cnt++;c[cnt].push_back(j);c[cnt].push_back(i);b[i].push_back(cnt);}}for (int i = 1; i <= cnt; i++) {for (auto y : c[i])for (auto x : a[y]) {char t;cout << '?' << ' ' << x << endl;scanf("\n%c", &t);if (t == 'Y') ans[x] = false;}cout << 'R' << endl;}int final = 0;for (int i = 1; i <= n; i++)final += ans[i];cout << '!' << ' ' << final << endl;}return 0;
}

Problem E. Cartesian Tree

考虑维护各个元素为根的区间 (l,r](l,r](l,r] 的元素出现次数的前缀和 Li,RiL_i,R_iLi​,Ri​ 。

若可以很好地维护它们,答案显然应为 ∑Ri−∑Li\sum R_i-\sum L_i∑Ri​−∑Li​ 。

则加入一个在 xxx 处的元素 vvv 对上述数组的影响是:
(1)(1)(1) 、对 [x,N][x,N][x,N] 内的 Li,RiL_i,R_iLi​,Ri​ 进行 +1+1+1
(2)(2)(2) 、对 (x,N](x,N](x,N] 内的 LiL_iLi​ 进行 Li=max{Li,v}L_i=max\{L_i,v\}Li​=max{Li​,v}
(3)(3)(3) 、对 [1,x)[1,x)[1,x) 内的 RiR_iRi​ 进行 Ri=min{Ri,v−1}R_i=min\{R_i,v-1\}Ri​=min{Ri​,v−1}
(4)(4)(4) 、将 (Lx,Rx)(L_x,R_x)(Lx​,Rx​) 修改为 (0,v)(0,v)(0,v)

用 SegmentTree Beats 分别维护 Li,RiL_i,R_iLi​,Ri​ 即可。

注意到全程中,空点始终满足 Li=RiL_i=R_iLi​=Ri​ ,不会影响答案。

时间复杂度 O(NLogN)O(NLogN)O(NLogN) 。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
const int INF  = 1e9 + 7;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
struct SegmentTreeChkmax {struct Node {ll sum; int lc, rc, tag, len;int cntMin, Min, Nin, tagMin;} a[MAXN * 2];int n, root, size;void update(int root) {a[root].cntMin = 0;a[root].sum = a[a[root].lc].sum + a[a[root].rc].sum;a[root].Min = min(a[a[root].lc].Min, a[a[root].rc].Min);a[root].Nin = min(a[a[root].lc].Nin, a[a[root].rc].Nin);if (a[a[root].lc].Min != a[root].Min) chkmin(a[root].Nin, a[a[root].lc].Min);else a[root].cntMin += a[a[root].lc].cntMin;if (a[a[root].rc].Min != a[root].Min) chkmin(a[root].Nin, a[a[root].rc].Min);else a[root].cntMin += a[a[root].rc].cntMin;}void build(int &root, int l, int r) {root = ++size;a[root].len = r - l + 1;if (l == r) {a[root].sum = 0;a[root].Min = 0;a[root].cntMin = 1;a[root].Nin = INF;return;}int mid = (l + r) / 2;build(a[root].lc, l, mid);build(a[root].rc, mid + 1, r);update(root);}void init(int x) {n = x;build(root, 1, n);}void pushdown(int root) {int lc = a[root].lc;int rc = a[root].rc;if (a[root].tag) {a[lc].tag += a[root].tag;a[lc].sum += 1ll * a[lc].len * a[root].tag;a[lc].Min += a[root].tag;a[lc].Nin += a[root].tag;a[rc].tag += a[root].tag;a[rc].sum += 1ll * a[rc].len * a[root].tag;a[rc].Min += a[root].tag;a[rc].Nin += a[root].tag;a[root].tag = 0;}if (a[root].tagMin) {int Min = min(a[lc].Min, a[rc].Min);if (a[lc].Min == Min) {a[lc].Min += a[root].tagMin;a[lc].tagMin += a[root].tagMin;a[lc].sum += 1ll * a[lc].cntMin * a[root].tagMin;}if (a[rc].Min == Min) {a[rc].Min += a[root].tagMin;a[rc].tagMin += a[root].tagMin;a[rc].sum += 1ll * a[rc].cntMin * a[root].tagMin;}a[root].tagMin = 0;}}void add(int root, int l, int r, int ql, int qr, int d) {if (l == ql && r == qr) {a[root].tag += d;a[root].Min += d;a[root].Nin += d;a[root].sum += 1ll * d * a[root].len;return;}pushdown(root);int mid = (l + r) / 2;if (mid >= ql) add(a[root].lc, l, mid, ql, min(mid, qr), d);if (mid + 1 <= qr) add(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d);update(root);}void add(int l, int r, int d) {add(root, 1, n, l, r, d);}void chkmax(int root, int l, int r, int ql, int qr, int d) {if (d <= a[root].Min) return;if (l == ql && r == qr) {if (d < a[root].Nin) {a[root].sum += 1ll * a[root].cntMin * (d - a[root].Min);a[root].tagMin += d - a[root].Min;a[root].Min = d;return;}pushdown(root);int mid = (l + r) / 2;chkmax(a[root].lc, l, mid, l, mid, d);chkmax(a[root].rc, mid + 1, r, mid + 1, r, d);update(root);return;}pushdown(root);int mid = (l + r) / 2;if (mid >= ql) chkmax(a[root].lc, l, mid, ql, min(mid, qr), d);if (mid + 1 <= qr) chkmax(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d);update(root);}void chkmax(int l, int r, int d) {chkmax(root, 1, n, l, r, d);}ll query(int root, int l, int r, int ql, int qr) {if (l == ql && r == qr) return a[root].sum;int mid = (l + r) / 2; ll ans = 0;pushdown(root);if (mid >= ql) ans += query(a[root].lc, l, mid, ql, min(qr, mid));if (mid + 1 <= qr) ans += query(a[root].rc, mid + 1, r, max(mid + 1, ql), qr);return ans;}ll query(int l, int r) {return query(root, 1, n, l, r);}
} L;
struct SegmentTreeChkmin {struct Node {ll sum; int lc, rc, tag, len;int cntMax, Max, Nax, tagMax;} a[MAXN * 2];int n, root, size;void update(int root) {a[root].cntMax = 0;a[root].sum = a[a[root].lc].sum + a[a[root].rc].sum;a[root].Max = max(a[a[root].lc].Max, a[a[root].rc].Max);a[root].Nax = max(a[a[root].lc].Nax, a[a[root].rc].Nax);if (a[a[root].lc].Max != a[root].Max) chkmax(a[root].Nax, a[a[root].lc].Max);else a[root].cntMax += a[a[root].lc].cntMax;if (a[a[root].rc].Max != a[root].Max) chkmax(a[root].Nax, a[a[root].rc].Max);else a[root].cntMax += a[a[root].rc].cntMax;}void build(int &root, int l, int r) {root = ++size;a[root].len = r - l + 1;if (l == r) {a[root].sum = 0;a[root].Max = 0;a[root].cntMax = 1;a[root].Nax = -INF;return;}int mid = (l + r) / 2;build(a[root].lc, l, mid);build(a[root].rc, mid + 1, r);update(root);}void init(int x) {n = x;build(root, 1, n);}void pushdown(int root) {int lc = a[root].lc;int rc = a[root].rc;if (a[root].tag) {a[lc].tag += a[root].tag;a[lc].sum += 1ll * a[lc].len * a[root].tag;a[lc].Max += a[root].tag;a[lc].Nax += a[root].tag;a[rc].tag += a[root].tag;a[rc].sum += 1ll * a[rc].len * a[root].tag;a[rc].Max += a[root].tag;a[rc].Nax += a[root].tag;a[root].tag = 0;}if (a[root].tagMax) {int Max = max(a[lc].Max, a[rc].Max);if (a[lc].Max == Max) {a[lc].Max += a[root].tagMax;a[lc].tagMax += a[root].tagMax;a[lc].sum += 1ll * a[lc].cntMax * a[root].tagMax;}if (a[rc].Max == Max) {a[rc].Max += a[root].tagMax;a[rc].tagMax += a[root].tagMax;a[rc].sum += 1ll * a[rc].cntMax * a[root].tagMax;}a[root].tagMax = 0;}}void add(int root, int l, int r, int ql, int qr, int d) {if (l == ql && r == qr) {a[root].tag += d;a[root].Max += d;a[root].Nax += d;a[root].sum += 1ll * d * a[root].len;return;}pushdown(root);int mid = (l + r) / 2;if (mid >= ql) add(a[root].lc, l, mid, ql, min(mid, qr), d);if (mid + 1 <= qr) add(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d);update(root);}void add(int l, int r, int d) {add(root, 1, n, l, r, d);}void chkmin(int root, int l, int r, int ql, int qr, int d) {if (d >= a[root].Max) return;if (l == ql && r == qr) {if (d > a[root].Nax) {a[root].sum += 1ll * a[root].cntMax * (d - a[root].Max);a[root].tagMax += d - a[root].Max;a[root].Max = d;return;}pushdown(root);int mid = (l + r) / 2;chkmin(a[root].lc, l, mid, l, mid, d);chkmin(a[root].rc, mid + 1, r, mid + 1, r, d);update(root);return;}pushdown(root);int mid = (l + r) / 2;if (mid >= ql) chkmin(a[root].lc, l, mid, ql, min(mid, qr), d);if (mid + 1 <= qr) chkmin(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d);update(root);}void chkmin(int l, int r, int d) {chkmin(root, 1, n, l, r, d);}ll query(int root, int l, int r, int ql, int qr) {if (l == ql && r == qr) return a[root].sum;int mid = (l + r) / 2; ll ans = 0;pushdown(root);if (mid >= ql) ans += query(a[root].lc, l, mid, ql, min(qr, mid));if (mid + 1 <= qr) ans += query(a[root].rc, mid + 1, r, max(mid + 1, ql), qr);return ans;}ll query(int l, int r) {return query(root, 1, n, l, r);}
} R;
int n, a[MAXN], home[MAXN];
int main() {read(n), L.init(n), R.init(n);for (int i = 1; i <= n; i++)read(a[i]), home[a[i]] = i;for (int i = 1; i <= n; i++) {int x = home[i];L.add(x, n, 1);R.add(x, n, 1);int cnt = L.query(x, x);if (x + 1 <= n) L.chkmax(x + 1, n, cnt);if (x - 1 >= 1) R.chkmin(1, x - 1, cnt - 1);L.add(x, x, 0 - cnt);R.add(x, x, i - cnt);printf("%lld\n", R.query(1, n) - L.query(1, n));}return 0;
}

Problem F. Making Shapes

问题等价于给各个向量赋上非负的系数,使得向量和为零向量,且各个坐标系的跨度 Sx,SyS_x,S_ySx​,Sy​ 均不超过 MMM ,跨度定义为正数项的和。求满足条件的方案数。

令横坐标正数项的和为 pxpxpx ,负数项和的绝对值为 nxnxnx ;
令纵坐标正数项的和为 pypypy ,负数项和的绝对值为 nynyny 。

则应当有 px=nx=Sx,py=ny=Sypx=nx=S_x,py=ny=S_ypx=nx=Sx​,py=ny=Sy​ 。

那么,按照传统的数位 DP 技巧,二进制拆分后,从高位向低位 DP ,
在状态中记录 px,nx,py,nypx,nx,py,nypx,nx,py,ny 表示直到当前二进制位 Sx−px,Sx−nx,Sy−py,Sy−nyS_x-px,S_x-nx,S_y-py,S_y-nySx​−px,Sx​−nx,Sy​−py,Sy​−ny 的余数,暴力转移即可。

时间复杂度 O(2N×N4V4LogM)O(2^N\times N^4V^4LogM)O(2N×N4V4LogM) 。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 45;
const int P = 998244353;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
int n, m, Log, a[MAXN], x[MAXN], y[MAXN], bit[MAXN];
int dp[2][MAXN][MAXN][MAXN][MAXN][2][2];
void update(int &x, int y) {x += y;if (x >= P) x -= P;
}
int main() {read(n), read(m);while (m != 0) {a[++Log] = m % 2;m >>= 1;}for (int i = 1; i <= n; i++) {read(x[i]), read(y[i]);bit[i] = 1 << (i - 1);}int lim = 32;dp[Log & 1][0][0][0][0][1][1] = 1;for (int i = Log, s = Log & 1, t = s ^ 1; i >= 1; i--, swap(s, t)) {memset(dp[t], 0, sizeof(dp[t]));for (int px = 0; px <= lim; px++)for (int py = 0; py <= lim; py++)for (int nx = 0; nx <= lim; nx++)for (int ny = 0; ny <= lim; ny++) {int vzz = dp[s][px][py][nx][ny][0][0];int vzo = dp[s][px][py][nx][ny][0][1];int voz = dp[s][px][py][nx][ny][1][0];int voo = dp[s][px][py][nx][ny][1][1];if (!(vzz || vzo || voz || voo)) continue;for (int s = 0; s <= (1 << n) - 1; s++) {int incpx = 0, incpy = 0, incnx = 0, incny = 0;for (int j = 1; j <= n; j++)if (s & bit[j]) {if (x[j] >= 0) incpx += x[j];else incnx -= x[j];if (y[j] >= 0) incpy += y[j];else incny -= y[j];}if (px >= incpx && py >= incpy && nx >= incnx && ny >= incny) {int tpx = (px - incpx) * 2;int tpy = (py - incpy) * 2;int tnx = (nx - incnx) * 2;int tny = (ny - incny) * 2;if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][a[i] == 0], voo);}}if (px + 1 >= incpx && py >= incpy && nx + 1 >= incnx && ny >= incny) {int tpx = (px + 1 - incpx) * 2;int tpy = (py - incpy) * 2;int tnx = (nx + 1 - incnx) * 2;int tny = (ny - incny) * 2;if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);update(dp[t][tpx][tpy][tnx][tny][0][a[i] == 0], vzo);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][a[i] == 0], voo);}}if (px >= incpx && py + 1 >= incpy && nx >= incnx && ny + 1 >= incny) {int tpx = (px - incpx) * 2;int tpy = (py + 1 - incpy) * 2;int tnx = (nx - incnx) * 2;int tny = (ny + 1 - incny) * 2;if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][0], voz);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][a[i] == 0][1], voo);}}if (px + 1 >= incpx && py + 1 >= incpy && nx + 1 >= incnx && ny + 1 >= incny) {int tpx = (px + 1 - incpx) * 2;int tpy = (py + 1 - incpy) * 2;int tnx = (nx + 1 - incnx) * 2;int tny = (ny + 1 - incny) * 2;if (tpx <= lim && tpy <= lim && tnx <= lim && tny <= lim) {update(dp[t][tpx][tpy][tnx][tny][0][0], vzz);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][0][1], vzo);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][0], voz);if (a[i] == 1) update(dp[t][tpx][tpy][tnx][tny][1][1], voo);}}}}}int ans = P - 1;for (int l1 = 0; l1 <= 1; l1++)for (int l2 = 0; l2 <= 1; l2++)update(ans, dp[0][0][0][0][0][l1][l2]);cout << ans << endl;return 0;
}

【CodeForces】Codeforces Round 616相关推荐

  1. 【cf】Codeforces 题解等汇总

    [cf]Codeforces Round #774 (Div. 2) 前4题 [cf]Codeforces Round #774 (Div. 2) 前4题_legend_yst的博客-CSDN博客 [ ...

  2. 【CF补题】【ABC】Codeforces Round #777 (Div. 2) C++代码

     A. Madoka and Math Dad [题意]求连续不带零且不相等位数的最大十进制数,使其位数之和为 n.有t个测试n [思考]根据样例我们就可以推测答案是121212...或212121. ...

  3. 【模拟】Codeforces 710C Magic Odd Square

    题目链接: http://codeforces.com/problemset/problem/710/C 题目大意: 构造一个N*N的幻方.任意可行解. 幻方就是每一行,每一列,两条对角线的和都相等. ...

  4. 【模拟】Codeforces 705A Hulk

    题目链接: http://codeforces.com/problemset/problem/705/A 题目大意: 给一个数N(N<=100),N=1时输出"I hate it&qu ...

  5. 【模拟】Codeforces 711A Bus to Udayland

    题目链接: http://codeforces.com/problemset/problem/711/A 题目大意: N个字符串,每个字符串5位,找到第一个出现两个OO的并改成++输出YES和改后字符 ...

  6. 【cf】Codeforces Round #784(Div 4)

    由于一次比赛被虐得太惨,,生发开始写blog的想法,于是便有了这篇随笔(找了个近期的cf比赛练练手(bushi))第一次写blog,多多包涵. 第二场cf比赛,第一场打的Div2,被虐太惨,所以第二场 ...

  7. 【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!

    题意:给你一个长度为n的数组,每个元素都在1~n之间,要你改变最少的元素,使得它变成一个1~n的排列.在保证改动最少的基础上,要求字典序最小. 预处理cnt数组,cnt[i]代表i在原序列中出现的次数 ...

  8. 【推导】Codeforces Round #364 (Div. 2) D. As Fast As Possible

    一种方法是二分总时间,复杂度O(nlogn). 另外我们可以证明,当所有人同时到达终点的时候,是最优的,因为没有人的时间"浪费"了. 我们又发现,每个人的运动过程总是两段,要么是走 ...

  9. 【暴力】Codeforces Round #398 (Div. 2) A. Snacktower

    题意不复述. 用个bool数组记录一下,如果某一天,当前剩下的最大的出现了的话,就输出一段. #include<cstdio> using namespace std; int n; bo ...

最新文章

  1. TensorFlow 学习(3)——MNIST机器学习入门
  2. 外部表不是预期的格式_超详细的CMDB介绍--概念、架构、模型、表设计及开源选择...
  3. ASP.NET页面的处理过程完全版_AX
  4. 用别的表格中数据进行计算机,tusimpleBI 做的图表,别的电脑可以打开吗?
  5. java web文件上传详解_java web图片上传和文件上传实例详解
  6. Java面试题:热情盛夏,分享Java大厂面试百题
  7. ASP.NET 2.0 - 如何于网页上新增包括图片在内的数据至数据库
  8. python教学笔记_python学习笔记(一)
  9. 三菱系统数据采集程序发布安装指引
  10. 联合投稿其乐融融 抖音共创助你大显身手
  11. PPTPDF文件转换成图片上传OSS
  12. 细思极恐的“25号宇宙实验”的心理学启示:过于富足+缺乏边界=沉沦与毁灭?
  13. 南邮matlab实验报告,南邮matlab实验报告.doc
  14. 太懒了,所以用小爱开楼下的门禁
  15. t30什么时间升级鸿蒙,性能升级富士旗舰无反X-T3新固件发布
  16. 苍蝇也是肉!ofo卖了遗留在印度的5000辆自行车
  17. 06 系统建模语言SysML——内部模块图
  18. Android 仿微博列表视频(一),静音播放
  19. Windows共享文件或打印机的方法【各种情况的集合】
  20. HTC Wildfire S|A510e刷机步骤

热门文章

  1. UWB定位的功能及应用场景解读
  2. ORA-01790:expression must have same datatype as corresponding expression
  3. Linux下高级C编程(学习总结)
  4. Kotlin最佳项目实战——欧瑞天气App
  5. 为什么蓝鸽的听力下载完还是听不了_如何攻克雅思听力?天天练习才能找到好的状态!...
  6. 山石防火墙做OSPF负载实例
  7. “互联网+”背景下使用微信公众号增强班主任工作与整合教学资源(泰微课)...
  8. 交调失真的意义及矢网实例测量方法
  9. Python轮子打包whl文件
  10. USACO 2.1 Ordered Fractions