Always kee|

园龄:粉丝:关注:

2023-10-16 23:00阅读: 54评论: 3推荐: 1

CSP模拟赛记录

CSP模拟赛记录

2023.10.15

A. 超速

题面有点绕 差评

直接二分

可爱的code捏
// Author: xiaruize
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
void chkmx(int &x, int y) {
if (y > x)
x = y;
}
void chkmi(int &x, int y) {
if (y < x)
x = y;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e5 + 10;
// bool st;
int n;
int v[N], l[N];
int m;
int a[N], f[N];
int q;
int lim;
// bool en;
bool check(int x) {
double t = 0;
rep(i, 1, n) { t = t + (double)l[i] / (v[i] + a[x]); }
return t < lim;
}
void solve() {
int s, t;
cin >> s >> t;
lim = t - s;
int l = 0, r = m;
while (l < r) {
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
cout << f[r] << endl;
}
signed main() {
freopen("speed.in", "r", stdin);
freopen("speed.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
cin >> n;
rep(i, 1, n) cin >> v[i];
rep(i, 1, n) cin >> l[i];
cin >> m;
a[m + 1] = 1e9;
rep(i, 1, m - 1) cin >> a[i];
rep(i, 1, m) cin >> f[i];
cin >> testcase;
while (testcase--) solve();
return 0;
}

B. 对常规的斗争

二次差分板子题 挺显然的

可爱的code捏
// Author: xiaruize
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
void chkmx(int &x, int y) {
if (y > x)
x = y;
}
void chkmi(int &x, int y) {
if (y < x)
x = y;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e5 + 10;
// bool st;
int n;
int a[N], s[N];
map<int, int> mp;
// bool en;
void solve() {
cin >> n;
rep(i, 1, n) {
cin >> a[i];
mp[a[i]] = 0;
}
rep(i, 1, n) {
int t = i - mp[a[i]];
s[1]++;
s[t + 1]--;
// cerr << t << endl;
t = n - i + 1;
s[t + 1]--;
s[n - mp[a[i]] + 2]++;
// rep(i, 0, 10)
// {
// cerr << s[i] << ' ';
// }
// cerr << endl;
mp[a[i]] = i;
}
rep(i, 1, n) s[i] += s[i - 1];
rep(i, 1, n) s[i] += s[i - 1];
rep(i, 1, n) { cout << s[i] << ' '; }
}
signed main() {
freopen("fight.in", "r", stdin);
freopen("fight.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

C. 海报

Part 1 不考虑查询

我们不考虑环,假设是在一条链上,那么一个很显然的dp状态为 dpi,j 表示考虑到第 i 个人, 从 i 开始往前连续 j 个人举海报

然后考虑环上的情况, 我们发现: 可以把最前面有多少个连续的人举海报这个东西扔到状态里面 即增加一维k,表示最前面有多少个连续的人举海报

时间复杂度 O(n) 空间复杂度 O(n)

Part 2 考虑查询

暴力修改重构, 时间复杂度 O(nq) ,显然不能通过

考虑用线段树维护 dp 数组,具体来说,线段树上每个节点存一个 dpi,j 表示当前节点表示的区间中,前 i 个人和后 j 个人都举海报,且第 i+1 个人和倒数第 j+1 个人不举海报的最大价值,合并的时候暴力转移即可

特别注意要特判区间全部选中的情况

时间复杂度 O(nlogn) 空间复杂度 O(n)

可爱的code捏
// Author: xiaruize
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
void chkmx(int &x, int y) {
if (y > x)
x = y;
}
void chkmi(int &x, int y) {
if (y < x)
x = y;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 4e4 + 10;
// bool st;
int n;
int a[N];
int q;
// bool en;
struct segment_tree {
#define ls p << 1
#define rs p << 1 | 1
struct node {
int dp[4][4];
} tr[N << 2];
void pushup(int p, int l, int r) {
memset(tr[p].dp, 0, sizeof(tr[p].dp));
int mid = l + r >> 1;
rep(i, 0, 3) {
if (i > mid - l + 1)
break;
rep(j, 0, 3) {
if (j > r - mid)
break;
rep(k, 0, 3) {
if (k > mid - l + 1)
break;
rep(d, 0, 3) {
if (d > r - mid)
break;
if (k + d > 3)
continue;
if (i == mid - l + 1 && j == r - mid) {
if (i + j > 3)
continue;
tr[p].dp[i + j][i + j] =
max(tr[p].dp[i + j][i + j], tr[ls].dp[i][i] + tr[rs].dp[j][j]);
} else if (i == mid - l + 1) {
if (i + d > 3)
continue;
tr[p].dp[i + d][j] = max(tr[p].dp[i + d][j], tr[ls].dp[i][i] + tr[rs].dp[d][j]);
} else if (j == r - mid) {
if (j + k > 3)
continue;
tr[p].dp[i][j + k] = max(tr[p].dp[i][j + k], tr[ls].dp[i][k] + tr[rs].dp[j][j]);
} else
tr[p].dp[i][j] = max(tr[p].dp[i][j], tr[ls].dp[i][k] + tr[rs].dp[d][j]);
}
}
}
}
}
void build(int p, int l, int r) {
if (l == r) {
tr[p].dp[1][1] = a[l];
return;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(p, l, r);
// cerr << p << ' ' << l << ' ' << r << endl;
// rep(i, 0, 3)
// {
// rep(j, 0, 3)
// {
// cerr << tr[p].dp[i][j] << ' ';
// }
// cerr << endl;
// }
}
void update(int p, int l, int r, int pos, int val) {
if (l == r) {
tr[p].dp[1][1] = val;
return;
}
int mid = l + r >> 1;
if (mid >= pos)
update(ls, l, mid, pos, val);
else
update(rs, mid + 1, r, pos, val);
pushup(p, l, r);
// cerr << p << ' ' << l << ' ' << r << endl;
// rep(i, 0, 3)
// {
// rep(j, 0, 3)
// {
// cerr << tr[p].dp[i][j] << ' ';
// }
// cerr << endl;
// }
}
int getans() {
int res = 0;
rep(i, 0, 3) {
rep(j, 0, 3) {
if (i + j <= 3) {
res = max(res, tr[1].dp[i][j]);
}
}
}
return res;
}
} seg;
void solve() {
cin >> n;
rep(i, 1, n) { cin >> a[i]; }
seg.build(1, 1, n);
cout << seg.getans() << endl;
cin >> q;
while (q--) {
int x, v;
cin >> x >> v;
seg.update(1, 1, n, x, v);
cout << seg.getans() << endl;
}
}
signed main() {
freopen("poster.in", "r", stdin);
freopen("poster.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

D. 机器人锦标赛

题面还是比较烦 但是其实暴力加就可以 遇到 1 显然就不用继续操作了

可爱的code捏
// Author: xiaruize
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
void chkmx(int &x, int y) {
if (y > x)
x = y;
}
void chkmi(int &x, int y) {
if (y < x)
x = y;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 3e5 + 10;
// bool st;
struct node {
int op, a, b;
};
vector<node> op[N];
vector<int> g[N], p[N], fa[N];
bool vis[N];
int n, m, s, res, f[N];
// bool en;
void upd(int x, int y) {
if (vis[x])
return;
g[x][y] = 1;
for (int v = y, t;; v = t) {
if (v == m * 2 - 2)
break;
t = fa[x][v];
if (op[x][t - m].op == 1)
g[x][t] = g[x][op[x][t - m].a] & g[x][op[x][t - m].b];
else
g[x][t] = g[x][op[x][t - m].a] | g[x][op[x][t - m].b];
}
if (g[x][m * 2 - 2]) {
vis[x] = true;
res++;
}
}
void solve() {
cin >> m >> n >> s;
rep(i, 1, n) {
g[i].resize(m * 2);
fa[i].resize(m * 2);
op[i].resize(m);
rep(j, 0, m - 2) {
cin >> op[i][j].a >> op[i][j].b >> op[i][j].op;
op[i][j].a--;
op[i][j].b--;
fa[i][op[i][j].a] = fa[i][op[i][j].b] = j + m;
}
}
rep(i, 0, m - 1) p[i].resize(n);
rep(i, 1, n) {
rep(j, 0, m - 1) {
int x;
cin >> x;
p[j][x] = i;
}
}
rep(i, 0, m - 1) {
while (res < s && f[i] < n) upd(p[i][f[i]++], i);
}
rep(i, 0, m - 1) cout << f[i] << ' ';
}
signed main() {
freopen("robot.in", "r", stdin);
freopen("robot.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

2023.10.15比赛总结

300 分没挂,最后一题不打暴力有点可惜

2023.10.16

A. 魔力子串

直接vectormap里面 没什么好说的

警示后人: 能用map就不要哈希

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e5 + 10;
// bool st;
int n;
string s;
int cnt[52];
map<vector<int>, int> mp;
map<char, int> chg;
int tot = 0;
// bool en;
int ch(char c) {
if (chg.count(c))
return chg[c];
return chg[c] = tot++;
}
void solve() {
cin >> n >> s;
rep(i, 0, n - 1) ch(s[i]);
vector<int> tmp(tot);
mp[tmp]++;
rep(i, 0, n - 1) {
cnt[ch(s[i])]++;
vector<int> tmp(tot);
rep(i, 0, tot - 2) {
tmp[i] = cnt[i + 1] - cnt[i];
// cerr << tmp[i] << ' ';
}
// cerr << endl;
mp[tmp]++;
}
int res = 0;
for (auto v : mp) {
// cerr << v.second << endl;
res += v.second * (v.second - 1) / 2;
res %= MOD;
}
cout << res << endl;
}
signed main() {
freopen("magic.in", "r", stdin);
freopen("magic.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

B. 吃树

结论题

  1. 当正好存在 nk 个节点的子树大小为 k 的倍数时, k 作为块的大小是合法的

  2. 对于每种合法的块的大小,有且仅有 1 种构造方案

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e6 + 10;
// bool st;
int n;
vector<int> g[N];
int siz[N], cnt[N];
// bool en;
void dfs(int x, int fa)
{
siz[x] = 1;
for (auto v : g[x])
{
if (v == fa)
continue;
dfs(v, x);
siz[x] += siz[v];
}
cnt[siz[x]]++;
}
int res = 0;
void calc(int x)
{
int c = 0;
for (int i = x; i <= n; i += x)
{
c += cnt[i];
}
if (c == n / x)
{
// cerr << x << endl;
res++;
}
}
void solve()
{
cin >> n;
rep(i, 1, n - 1)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
rep(i, 1, n)
{
if (i * i > n)
break;
if (n % i == 0)
{
calc(i);
if (i * i != n)
calc(n / i);
}
}
cout << res << endl;
}
signed main()
{
freopen("eat.in", "r", stdin);
freopen("eat.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--)
solve();
return 0;
}

C. 弹弹床

想不到状态的可爱 dp 题捏~~~

对于 [1,i] 这个区间, 必然被从右侧进入再出来一定次数, 所以令 dpi,j 表示区间 [1,i] 在若干步以后, 剩下 j 个向右的没有确定终点

dpi,j={dpi1,j×j+dpi1,j1,Si=Rdpi1,j×j+dpi1,j+1×(j+1)×j,Si=L

可以获得60分的好成绩

考虑怎么处理中间的数值, 发现上述dp可以反过来再做一次, 算出区间 [i,n] , 剩下 j 个向左的方案数

然后枚举终点, 左右匹配即可

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 5e3 + 10;
// bool st;
int n;
char s[N];
int f[N][N], g[N][N];
int fac[N];
// bool en;
void solve() {
cin >> n;
cin >> (s + 1);
if (n == 1) {
cout << "1" << endl;
return;
}
f[0][0] = 1;
rep(i, 1, n) {
rep(j, 1, i) {
if (s[i] == 'L')
f[i][j] = (f[i - 1][j] * j % MOD + f[i - 1][j + 1] * (j + 1) % MOD * j % MOD) % MOD;
else
f[i][j] = (f[i - 1][j - 1] + f[i - 1][j] * j % MOD) % MOD;
f[i][j] %= MOD;
}
}
g[n + 1][0] = 1;
per(i, n, 1) {
rep(j, 1, n - i + 1) {
if (s[i] == 'R')
g[i][j] = (g[i + 1][j] * j % MOD + g[i + 1][j + 1] * (j + 1) % MOD * j % MOD) % MOD;
else
g[i][j] = (g[i + 1][j - 1] + g[i + 1][j] * j % MOD) % MOD;
g[i][j] %= MOD;
}
}
fac[0] = 1;
rep(i, 1, n) fac[i] = fac[i - 1] * i % MOD;
rep(i, 1, n) {
int res = 0;
rep(j, 0, i - 1) {
if (j)
(res += fac[j] * fac[j - 1] % MOD * f[i - 1][j] % MOD * g[i + 1][j - 1] % MOD) %= MOD;
(res += fac[j] * fac[j] % MOD * f[i - 1][j] % MOD * g[i + 1][j] % MOD * 2 % MOD) %= MOD;
(res += fac[j + 1] * fac[j] % MOD * f[i - 1][j] % MOD * g[i + 1][j + 1] % MOD) %= MOD;
}
cout << res << ' ';
}
}
signed main() {
freopen("jump.in", "r", stdin);
freopen("jump.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

D. 数星星

小丑了 上次补这题是ACV

这道题去年做过 我记得 x–r--z- 去年还补过 可惜没有什么用 --zc

将查询按照右端点排序,可以考虑把所有贡献算在当前节点的最后一次出现上

那么,当处理到当前右端点时,直接查询左端点即可

然后用一个set去维护每个区间的覆盖情况,用树状数组维护每个时刻的值,树剖做链上修改

巨大的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
#define endl '\n'
int max(int a, int b) {
if (a > b)
return a;
return b;
}
int min(int a, int b) {
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e5 + 10;
// bool st;
int n, m, q;
int a[N];
vector<int> g[N];
int dep[N];
int siz[N];
int fa[N];
int top[N];
int son[N], sum[N];
int dfn[N], rnk[N], tot;
// bool en;
void dfs(int x, int y) {
dep[x] = dep[y] + 1;
siz[x] = 1;
fa[x] = y;
for (auto v : g[x]) {
if (v == y)
continue;
dfs(v, x);
siz[x] += siz[v];
if (siz[v] > siz[son[x]])
son[x] = v;
}
}
void dfs2(int x, int tp) {
dfn[x] = ++tot;
rnk[tot] = x;
top[x] = tp;
sum[tot] = sum[tot - 1] + a[x];
if (son[x])
dfs2(son[x], tp);
for (auto v : g[x]) {
if (v != son[x] && v != fa[x]) {
dfs2(v, v);
}
}
}
struct BIT {
int tr[N];
void add(int x, int v) {
while (x) {
tr[x] += v;
x -= x & -x;
}
}
int sum(int x) {
int res = 0;
while (x <= m) {
res += tr[x];
x += x & -x;
}
return res;
}
} tr;
pii w[N];
struct query {
int l, r, id;
bool operator<(const query &y) const { return l < y.l; }
} s[N];
set<query> st;
bool cmp(query a, query b) { return a.r < b.r; }
int ans[N];
void add(int l, int r, int id) {
while (1) {
auto it = st.upper_bound({ r, 0, 0 });
if (it == st.begin())
break;
it--;
if ((*it).r < l)
break;
auto [xl, xr, xid] = (*it);
// cerr << xl << ' ' << xr << ' ' << xid << endl;
st.erase(it);
tr.add(xid, sum[max(l, xl) - 1] - sum[min(r, xr)]);
if (xl < l)
st.insert({ xl, l - 1, xid });
if (xr > r)
st.insert({ r + 1, xr, xid });
}
tr.add(id, sum[r] - sum[l - 1]);
st.insert({ l, r, id });
}
void calc(int u, int v, int id) {
// cerr << u << ' ' << v << endl;
while (top[u] != top[v]) {
if (dfn[top[u]] < dfn[top[v]])
swap(u, v);
add(dfn[top[u]], dfn[u], id);
u = fa[top[u]];
}
if (dfn[u] > dfn[v])
swap(u, v);
add(dfn[u], dfn[v], id);
}
void solve() {
cin >> n >> m >> q;
rep(i, 1, n) { cin >> a[i]; }
rep(i, 1, n - 1) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
dfs2(1, 1);
rep(i, 1, m) { cin >> w[i].first >> w[i].second; }
rep(i, 1, q) {
cin >> s[i].l >> s[i].r;
s[i].id = i;
}
sort(s + 1, s + q + 1, cmp);
rep(i, 1, q) {
rep(j, s[i - 1].r + 1, s[i].r) calc(w[j].first, w[j].second, j);
ans[s[i].id] = tr.sum(s[i].l);
}
rep(i, 1, q) cout << ans[i] << endl;
}
signed main() {
freopen("star.in", "r", stdin);
freopen("star.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--) solve();
return 0;
}

20231016比赛总结

拿了大众分 没有严重的挂分

O(nnlog2n)=O(n2)

写代码之前先好好算时间复杂度qwq

2023.10.17

A. 子段排序

构造题 注意到排序操作 = ai<aj 时的 swap

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e3 + 10;
// bool st;
int n;
int a[N], b[N];
// bool en;
void solve()
{
cin >> n;
rep(i, 1, n)
{
cin >> a[i];
}
rep(i, 1, n) cin >> b[i];
vector<pii> res;
rep(i, 1, n)
{
if (a[i] != b[i])
{
int p = i, mi = INF;
while (a[p] != b[i] && p <= n)
{
mi = min(mi, a[p]);
p++;
}
// cerr << i << ' ' << p << endl;
if (a[p] > mi || p > n)
{
cout << "-1" << endl;
return;
}
per(j, p - 1, i)
{
res.push_back({j, j + 1});
swap(a[j], a[j + 1]);
}
}
// rep(j, 1, n) cerr << a[j] << ' ';
// cerr << endl;
}
cout << "0" << endl;
cout << res.size() << endl;
for (auto v : res)
cout << v.first << ' ' << v.second << endl;
}
signed main()
{
freopen("subarray.in", "r", stdin);
freopen("subarray.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
cin >> testcase;
while (testcase--)
solve();
return 0;
}

B. 伪快速排序

dpi,j 表示 [1,i] , 最后一个数为 j 的方案数

dpi,j=k=0i1dpk,j1dpik1,j1(i1k)

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
int MOD = 1000000007;
const int N = 3e2 + 10;
// bool st;
int dp[N][N];
int c[N][N];
// bool en;
void solve()
{
int n, k;
cin >> n >> k;
k = min(k, n);
cout << dp[n][k] << endl;
}
signed main()
{
freopen("qsort.in","r",stdin);
freopen("qsort.out","w",stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
cin >> testcase >> MOD;
c[0][0] = 1;
rep(i, 1, 300)
{
c[i][0] = c[i][i] = 1;
rep(j, 1, 300)
{
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
}
dp[0][i] = 1;
}
rep(i, 1, 300)
{
dp[i][1] = 1;
rep(j, 2, 300)
{
rep(p, 0, i - 1)
{
(dp[i][j] += dp[p][j - 1] * dp[i - p - 1][j - 1] % MOD * c[i - 1][p] % MOD) %= MOD;
}
}
}
while (testcase--)
solve();
return 0;
}

C. 二进制式

表达式题, 先见表达式树, 考虑 dfs 算每个节点为 1 的概率

然后从根向下 dfs 即可算每个点的答案

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 998244353;
const int N = 2e5 + 10;
// bool st;
int n, len;
char s[N << 4];
struct node
{
int l, r;
int op, val; // 1 and 2 or 3 xor
} p[N << 2];
int tot = 0, cnt = 0;
stack<int> st, ope;
int res[N];
// bool en;
int qpow(int a, int b)
{
int res = 1;
while (b)
{
if (b & 1)
res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
void dfs(int x)
{
if (p[x].l > n)
dfs(p[x].l);
if (p[x].r > n)
dfs(p[x].r);
if (p[x].op == 1)
p[x].val = p[p[x].l].val * p[p[x].r].val % MOD;
else if (p[x].op == 2)
p[x].val = (1 - (1 - p[p[x].l].val + MOD) % MOD * (1 - p[p[x].r].val + MOD) % MOD + MOD) % MOD;
else
p[x].val = ((1 - p[p[x].l].val + MOD) % MOD * p[p[x].r].val % MOD + (1 - p[p[x].r].val + MOD) % MOD * p[p[x].l].val % MOD) % MOD;
}
void calc(int x, int v)
{
if (x <= n)
{
res[x] = v;
return;
}
if (p[x].op == 1)
{
calc(p[x].l, v * p[p[x].r].val % MOD);
calc(p[x].r, v * p[p[x].l].val % MOD);
}
else if (p[x].op == 2)
{
calc(p[x].l, v * (1 - p[p[x].r].val + MOD) % MOD);
calc(p[x].r, v * (1 - p[p[x].l].val + MOD) % MOD);
}
else
{
calc(p[x].l, v);
calc(p[x].r, v);
}
}
void solve()
{
cin >> n >> (s + 1);
len = strlen(s + 1);
cnt = n;
int inv2 = qpow(2, MOD - 2);
rep(i, 1, n)
{
p[i].val = inv2;
}
rep(i, 1, len)
{
if (s[i] == 'x')
st.push(++tot);
else if (s[i] == '&')
ope.push(1);
else if (s[i] == '|')
ope.push(2);
else if (s[i] == '^')
ope.push(3);
else if (s[i] == ')')
{
int b = st.top();
st.pop();
int a = st.top();
st.pop();
int opr = ope.top();
ope.pop();
p[++cnt] = {a, b, opr};
st.push(cnt);
}
}
dfs(cnt);
calc(cnt, 1);
rep(i, 1, n)
{
cout << res[i] << endl;
}
}
signed main()
{
freopen("binary.in","r",stdin);
freopen("binary.out","w",stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--)
solve();
return 0;
}

D. 网格图

挖坑待填

20231017比赛总结

除了最后一题没有挂分

认真看数据范围,下面不一定包括上面!!!

2023.10.18

A. 玛雅历

形似儒略日, 稍微简单一点, 注意到公元前很烦, 考虑直接将公元前向后平移 1 年, 然后使公元 0 年存在

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 2e5 + 10;
// bool st;
int cnt400 = 0;
int a[N];
int num[10] = {0, 23040000000, 1152000000, 57600000, 2880000, 144000, 7200, 360, 20, 1};
int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// bool en;
void solve()
{
rep(i, 1, 8)
{
cin >> a[i];
char c;
cin >> c;
}
cin >> a[9];
int daycnt = 0;
rep(i, 1, 9) daycnt = daycnt + num[i] * a[i];
// cerr << daycnt << endl;
int yearcnt = daycnt / cnt400;
daycnt %= cnt400;
int yearnum = -3113 + yearcnt * 400, monthnum = 8;
int curyearnum = 0;
if ((yearnum + 1) % 4 == 0 && ((yearnum + 1) % 100 != 0 || (yearnum + 1) % 400 == 0))
curyearnum = 366;
else
curyearnum = 365;
while (daycnt >= curyearnum)
{
daycnt -= curyearnum;
yearnum++;
if ((yearnum + 1) % 4 == 0 && ((yearnum + 1) % 100 != 0 || (yearnum + 1) % 400 == 0))
curyearnum = 366;
else
curyearnum = 365;
}
if (yearnum % 4 == 0 && (yearnum % 100 != 0 || yearnum % 400 == 0))
month[2] = 29;
while (daycnt >= month[monthnum])
{
daycnt -= month[monthnum];
monthnum++;
if (monthnum > 12)
{
monthnum = 1;
yearnum++;
if (yearnum % 4 == 0 && (yearnum % 100 != 0 || yearnum % 400 == 0))
month[2] = 29;
else
month[2] = 28;
}
}
int daynum = 11;
while (daycnt)
{
daycnt--;
daynum++;
if (daynum > month[monthnum])
{
daynum = 1;
monthnum++;
if (monthnum > 12)
{
monthnum = 1;
yearnum++;
if (yearnum % 4 == 0 && (yearnum % 100 != 0 || yearnum % 400 == 0))
month[2] = 29;
else
month[2] = 28;
}
}
}
if (yearnum <= 0)
cout << daynum << ' ' << monthnum << ' ' << -(yearnum - 1) << " BC" << endl;
else
cout << daynum << ' ' << monthnum << ' ' << yearnum << endl;
}
signed main()
{
freopen("maya.in", "r", stdin);
freopen("maya.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
cin >> testcase;
rep(i, 0, 399)
{
if (i % 4 == 0 && (i % 100 != 0 || i % 400 == 0))
cnt400 += 366;
else
cnt400 += 365;
}
// cerr << cnt400 << endl;
while (testcase--)
solve();
return 0;
}

B. 大融合

如题, 大融合, 可以拆成 2

第一部分算最小的 S, 直接map即可, 考场差点写 trie

第二部分显然二分, 考虑check, 可以令 dpi,j 表示到第 i 行, 第 j 列最多获得多少

显然这个 dp 可以单调队列优化

发现 3 个机器人分别走分别贡献其实是诈骗条件, 和只有一个走并贡献 100% 等价

可爱的code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e3 + 10;
// bool st;
int n, m, q, d;
map<int, bool> mp;
int minS;
int dp[N][N];
int a[N][N], col[N][N];
// bool en;
int solveminS()
{
cin >> n >> m >> q >> d;
rep(i, 1, m)
{
int x;
cin >> x;
int tmp = 10;
while (tmp <= x * 10)
{
// cerr << x % tmp << endl;
mp[x % tmp] = true;
tmp *= 10;
}
}
int res = 0;
rep(i, 1, q)
{
int l, b, v;
cin >> l >> b >> v;
if (!mp.count(b))
res += v;
}
return res;
}
bool check(int x)
{
int ld = max(1, d - x), rd = min(n, d + x);
memset(dp, -0x3f, sizeof(dp));
dp[1][1] = 0;
deque<pii> que[N][2];
int res = 0;
rep(i, 1, n)
{
deque<pii> cur[2];
rep(j, 1, n)
{
while (!cur[0].empty() && cur[0].front().second < j - rd)
cur[0].pop_front();
while (!cur[1].empty() && cur[1].front().second < j - rd)
cur[1].pop_front();
while (!que[j][0].empty() && que[j][0].front().second < j - rd)
que[j][0].pop_front();
while (!que[j][1].empty() && que[j][1].front().second < j - rd)
que[j][1].pop_front();
if (j > ld)
{
while (!cur[col[i][j - ld]].empty() && cur[col[i][j - ld]].back().first <= dp[i][j - ld])
cur[col[i][j - ld]].pop_back();
cur[col[i][j - ld]].push_back({dp[i][j - ld], j - ld});
}
if (i > ld)
{
while (!que[j][col[i - ld][j]].empty() && que[j][col[i - ld][j]].back().first <= dp[i - ld][j])
que[j][col[i - ld][j]].pop_back();
que[j][col[i - ld][j]].push_back({dp[i - ld][j], i - ld});
}
if (!cur[0].empty())
dp[i][j] = max(dp[i][j], cur[0].front().first + a[i][j] + (col[i][j] == 0));
if (!cur[1].empty())
dp[i][j] = max(dp[i][j], cur[1].front().first + a[i][j] + (col[i][j] == 1));
if (!que[j][0].empty())
dp[i][j] = max(dp[i][j], que[j][0].front().first + a[i][j] + (col[i][j] == 0));
if (!que[j][1].empty())
dp[i][j] = max(dp[i][j], que[j][1].front().first + a[i][j] + (col[i][j] == 1));
res = max(res, dp[i][j]);
// cerr << dp[i][j] << ' ';
}
// cerr << endl;
}
// cerr << x << ' ' << res << endl;
return res >= minS;
}
void solve()
{
rep(i, 1, n)
{
rep(j, 1, n)
{
cin >> col[i][j];
col[i][j]--;
}
}
rep(i, 1, n)
{
rep(j, 1, n)
{
cin >> a[i][j];
}
}
int l = 0, r = n;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
if (check(r))
cout << r << endl;
else
cout << "-1" << endl;
}
signed main()
{
freopen("harbinbeer.in", "r", stdin);
freopen("harbinbeer.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
minS = solveminS();
// cerr << minS << endl;
solve();
return 0;
}

C. 好 ♂ 朋 ♂ 友

卡常狗能不能死一死啊

很巧妙的性质: 同一个左端点的所有区间的 or 值最多只有 30 种情况

对于每个左端点, 二分或者倍增+st表, 算出每一段的位置和值, 对于合法的段区间 +1

将查询离线, 按左端点排序, 对于每一个查询, 先将 ql 左侧的节点作为左端点的贡献都去掉, 再在线段树上查询当前的答案

被卡常了qwq

被卡常的巨大code捏
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define debug(x) cerr << #x << ": " << x << endl
#define double long double
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
int min(int a, int b)
{
if (a < b)
return a;
return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e5 + 10;
const int M = 1e6 + 10;
// bool st;
int n, k, t;
int a[N];
set<int> s;
int res[M];
int st[N][20];
int lg[N];
pair<pii, int> q[M];
vector<pii> vec[N];
// bool en;
struct segment_tree
{
#define ls p << 1
#define rs p << 1 | 1
struct node
{
int sum, laz;
} tr[N << 2];
void pushup(int p)
{
tr[p].sum = tr[ls].sum + tr[rs].sum;
}
void pushdown(int p, int l, int r)
{
int mid = l + r >> 1;
tr[ls].sum += (mid - l + 1) * tr[p].laz;
tr[ls].laz += tr[p].laz;
tr[rs].sum += (r - mid) * tr[p].laz;
tr[rs].laz += tr[p].laz;
tr[p].laz = 0;
}
void update(int p, int l, int r, int ll, int rr, int val)
{
if (ll <= l && r <= rr)
{
tr[p].sum += (r - l + 1) * val;
tr[p].laz += val;
return;
}
pushdown(p, l, r);
int mid = l + r >> 1;
if (ll <= mid)
update(ls, l, mid, ll, rr, val);
if (rr > mid)
update(rs, mid + 1, r, ll, rr, val);
pushup(p);
}
int query(int p, int l, int r, int ll, int rr)
{
if (ll <= l && r <= rr)
return tr[p].sum;
pushdown(p, l, r);
int mid = l + r >> 1;
int res = 0;
if (ll <= mid)
res += query(ls, l, mid, ll, rr);
if (rr > mid)
res += query(rs, mid + 1, r, ll, rr);
return res;
}
} seg;
int get(int l, int r)
{
int t = lg[r - l + 1];
return (st[l][t] | st[r - (1 << t) + 1][t]);
}
void solve()
{
cin >> n >> t >> k;
rep(i, 1, k)
{
int x;
cin >> x;
s.insert(x);
}
lg[1] = 0;
rep(i, 1, n)
{
if (i != 1)
lg[i] = lg[i >> 1] + 1;
cin >> a[i];
st[i][0] = a[i];
}
rep(i, 1, 19)
{
for (int j = 1; j + (1 << i) - 1 <= n; j++)
{
st[j][i] = st[j][i - 1] | st[j + (1 << i - 1)][i - 1];
}
}
rep(i, 1, n)
{
int la = i - 1;
int j = i;
while (j <= n)
{
per(p, 19, 0)
{
if (j + (1 << p) > n)
continue;
if (get(i, j + (1 << p)) == get(i, j))
j = j + (1 << p);
}
if (s.find(get(i, j) % 10) != s.end())
{
vec[i].push_back({la + 1, j});
seg.update(1, 1, n, la + 1, j, 1);
}
// cerr << i << ' ' << la + 1 << ' ' << j << endl;
la = j;
j++;
}
}
rep(i, 1, t)
{
cin >> q[i].first.first >> q[i].first.second;
q[i].second = i;
}
sort(q + 1, q + t + 1);
int p = 1;
rep(i, 1, t)
{
// cerr << q[i].first.first << ' ' << q[i].first.second << endl;
while (p < q[i].first.first)
{
for (auto v : vec[p])
seg.update(1, 1, n, v.first, v.second, -1);
p++;
}
res[q[i].second] = seg.query(1, 1, n, q[i].first.first, q[i].first.second);
}
rep(i, 1, t) cout << res[i] << '\n';
}
signed main()
{
freopen("friend.in", "r", stdin);
freopen("friend.out", "w", stdout);
// cerr<<(&en-&st)/1024.0/1024.0<<endl;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--)
solve();
return 0;
}

D. 图的直径

挖坑待补

20231018比赛总结

2 题还好, T1第一遍写忽略了很多细节, T2假的代码过了乐

T3注意常数(卡常狗死一死)

能拿的分应该都拿到了吧

2023.10.19

A. 潜艇

本文作者:xiaruize's Blog

本文链接:https://www.cnblogs.com/xiaruize/p/17768600.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xiaruize  阅读(54)  评论(3编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起