2023 CCPC 深圳

D. Bot Brothers

有一棵 \(n\) 个点的树,\(m\) 个叶子,编号为 \(1∼m\)。两人在树上博弈,均从根出发,轮流行动,每次走向一个当前所在节点的子节点,如果在叶子就不移动。最终如果两人所在叶子编号一个是另一个 \(+1\)(\(\bmod m\) 意义下),则 \(+1\) 的一方获胜。\(m < n \leq 10^5\)。

Sol:博弈,哈希

首先后手是一定不败的,因为后手可以始终跟着先手,最终达到相同的叶子节点。

那么现在考虑什么样的情况下后手必胜。记 \(S_x\) 代表 \(x\) 子树内叶子节点的集合,\(T_x\) 代表 \(x\) 子树内叶子节点 \(+1\) 的集合。假设先手在 \(x\),后手在 \(y\),且 \(dep[x] = dep[y]\),其中 \(dep[x]\) 代表 \(x\) 的深度。

如果 \(T_x \nsubseteq S_y\),则先手一定可以一直向不存在于 \(S_y\) 中的叶子节点移动,因为 \(y\) 也只能往下移动到 \(y'\),并且 \(S_y' \subseteq S_y\),所以后手永远无法移动到获胜的叶子节点处。

所以后手的移动要始终保证 \(T_x \subseteq S_y\),也就是说,当先手从 \(x\) 移动到其儿子时,对于 \(x\) 的每个儿子 \(x'\) 一定存在唯一的 \(y\) 的儿子 \(y'\),使得 \(T_{x'} \subseteq S_{y'}\)。根据该性质,定义 \(dfs(x, y, fx, fy)\) 代表先手在 \(x\),后手在 \(y\),且 \(x\) 的父亲为 \(fx\),\(y\) 的父亲为 \(fy\) 时,后手是否必胜。枚举所有合法的 \(x'\) 和 \(y'\) 递归解决即可。因为如果后手必胜,每个 \(x'\) 一定存在唯一的 \(y\) 的儿子 \(y'\),所以只有 \(O(m)\) 种结果,所以复杂度为 \(O(m \log n)\),其中的 \(\log n\) 是通过 map 来确定与 \(x'\) 对应的 \(y'\)。注意当某个人已经到叶子节点的时候,直接退出即可。至于为什么 \(x'\) 一定存在唯一的 \(y\) 的儿子 \(y'\),下面的方法可以回答。

但是根据该性质,存在更优秀的做法,观察发现后手必胜时树的结构十分特殊,即相同深度的点的叶子节点集合 \(S\) 形如 \(\{a, a + x, a + 2x\dots\}\),且 \(|S| = \frac{m}{sz}\),其中 \(sz\) 为该深度节点个数。即,将相同深度的点按照 \(a\) 排序后,一定有 \(\forall i< sz,T_i = S_{i + 1}\),通过哈希 check 即可。需要注意的是,如果某个叶子节点的父亲只有 \(1\) 个儿子,我们需要删掉该父亲,直到父亲存在 \(2\) 个儿子以上为止。时间复杂度 \(O(n)\)。

// O(nlogn)
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define endl '\n'
using ll = long long;
using ull = unsigned long long;
const int N = 100010;
mt19937_64 rnd(time(0)); int n, m, dep[N];
ull hs[N], S[N], T[N];
vector<int> adj[N];
bool valid; inline void dfs(int u, int par) {
dep[u] = dep[par] + 1;
int c = 0;
S[u] = T[u] = 0;
for (auto v : adj[u]) if (v != par) {
c += 1;
dfs(v, u);
S[u] += S[v];
T[u] += T[v];
}
if (c == 0) {
S[u] = hs[u];
T[u] = hs[u % m + 1];
}
} inline void dfs(int x, int y, int fx, int fy) {
if (x <= m || y <= m) return;
map<ull, int> mp;
for (auto v : adj[x]) if (v != fx) {
mp[T[v]] = v;
}
for (auto v : adj[y]) if (v != fy) {
if (!mp.count(S[v])) {
valid = false;
return;
}
dfs(mp[S[v]], v, x, y);
if (!valid) return;
}
} void solve() {
cin >> n >> m;
valid = true;
for (int i = 1; i <= n; ++i) hs[i] = rnd();
for (int i = 1; i <= n; ++i) {
adj[i].clear();
}
for (int i = 1; i < n; ++i) {
int u, v; cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
dfs(n, 0);
dfs(n, n, 0, 0);
if (valid) cout << "Doddle\n";
else cout << "Tie\n";
}
signed main(void) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int Test = 1;
cin >> Test;
while (Test--) solve();
return 0;
}
// O(n)
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define endl '\n'
using ll = long long;
using ull = unsigned long long;
const int N = 100010;
mt19937_64 rnd(time(0)); int n, m, dep[N];
bool valid[N];
ull hs[N];
vector<int> adj[N];
vector<int> node[N]; // node[i] 代表深度为 i 的所有节点
struct Info {
int id; // 子树内最小的叶子节点编号
int sz; // 子树内叶子节点个数
ull hs1; // 子树内叶子节点编号的哈希和
ull hs2; // 子树内叶子 (节点编号 + 1) 的哈希和
} val[N]; inline void dfs(int u, int par) {
dep[u] = dep[par] + 1;
int c = 0;
val[u].id = n + 1;
val[u].hs1 = val[u].hs2 = 0;
val[u].sz = 0;
for (auto v : adj[u]) if (v != par) {
c += 1;
dfs(v, u);
val[u].id = min(val[u].id, val[v].id);
val[u].hs1 += val[v].hs1;
val[u].hs2 += val[v].hs2;
val[u].sz += val[v].sz;
}
if (c == 0) {
val[u].id = u;
val[u].hs1 = hs[u];
int v = u + 1;
if (v > m) v = 1;
val[u].hs2 = hs[v];
val[u].sz = 1;
} else if (c == 1 && val[u].sz == 1) {
valid[u] = false;
}
} inline void dfs1(int u, int par) {
if (!valid[u]) {
node[dep[u]].pb(val[u].id);
return;
}
node[dep[u]].pb(u);
for (auto v : adj[u]) if (v != par) {
dfs1(v, u);
}
} void solve() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) hs[i] = rnd();
for (int i = 1; i <= n; ++i) {
adj[i].clear();
node[i].clear();
valid[i] = true;
}
for (int i = 1; i < n; ++i) {
int u, v; cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
dfs(n, 0);
dfs1(n, 0);
for (int i = 2; i <= n; ++i) {
if (node[i].size() == 0) break;
sort(all(node[i]), [&](auto a, auto b) {
return val[a].id < val[b].id;
});
int x = node[i].size();
for (int j = 0; j < x - 1; ++j) {
int u = node[i][j], v = node[i][j + 1];
if (val[u].hs2 != val[v].hs1) {
cout << "Tie\n";
return;
}
}
}
cout << "Doddle\n";
}
signed main(void) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int Test = 1;
cin >> Test;
while (Test--) solve();
return 0;
}

E. Two in One

给定长度为 \(n\) 的序列 \(a\),找到一个区间以及在该区间中选择两种颜色,使得两种颜色的出现次数的二进制或最大。\(n \leq 10^5, a_i \leq n\)。

Sol:贪心,结论

不妨考虑在 \([1, n]\) 中选择两种颜色,若选择的两种颜色的出现次数分别为 \(x, y\),存在以下 \(2\) 种情况:

  • 若 \(\text{highbit}(x) = \text{highbit}(y)\),其中 \(\text{highbit}(x)\) 代表 \(x\) 在二进制下最高的 \(1\) 所在位,记 \(t = \text{highbit}(x)\)。

    不难证明,在区间 \([1, n]\) 不断缩减的过程中(要么 \(x\) 减少 \(1\),要么 \(y\) 减少 \(1\)),一定存在某个时刻,使得在当前区间中某一个颜色的出现次数的 \(\text{highbit}\) 仍为 \(t\),而另一个颜色的出现次数恰好为 \(2^t - 1\)。此时两种颜色的出现次数的二进制或最大,等于 \(2^{t + 1} - 1\)。

    贪心的,只需要选择 \([1, n]\) 中出现次数最多、次多的两种颜色即可。

  • 若 \(\text{highbit}(x) \neq \text{highbit}(y)\),记 \(t = \text{highbit}(x\ \&\ y)\)。

    不难证明,在区间 \([1, n]\) 不断缩减的过程中(要么 \(x\) 减少 \(1\),要么 \(y\) 减少 \(1\)),一定存在某个时刻,使得在当前区间中某一个颜色的出现次数仍 \(\geq 2^t\),而另一个颜色的出现次数恰好为 \(2^t - 1\),并且 \(x, y\) 高于 \(t\) 位的二进制不会改变。此时两种颜色的出现次数的二进制或最大,等于 \(x \mid y \mid 2^{\text{highbit}(x\ \&\ y)} - 1\)。

    贪心的,只需要选择 \([1, n]\) 中出现次数最多、次多的两种颜色即可。

综上,假设 \([1, n]\) 中出现次数最多、次多的颜色出现次数分别为 \(x, y\),则答案一定为 \(x \mid y \mid 2^{\text{highbit}(x\ \&\ y)} - 1\),注意特判 \(\text{highbit}(x\ \&\ y) = 0\) 的情况。

时间复杂度:\(O(n)\)。

#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define int long long
#define pb push_back
#define endl '\n'
using ll = long long;
const ll mod = 1000000007;
const ll INF = 1ll << 60;
const int inf = 1 << 30;
const int N = 200010; void solve() {
int n; cin >> n;
vector<int> c(n + 1);
int mx = 0, sc = 0;
for (int i = 1; i <= n; ++i) {
int x; cin >> x;
c[x] += 1;
}
sort(c.begin() + 1, c.begin() + n + 1, greater<>());
int x = c[1], y = c[2];
if (__lg(x) == __lg(y)) {
cout << (1 << __lg(x) + 1) - 1 << endl;
} else {
cout << (x | y | ((x & y) ? (1 << __lg(x & y)) - 1 : 0)) << endl;
}
}
signed main(void) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int Test = 1;
cin >> Test;
while (Test--) solve();
return 0;
}

K. Quad Kingdoms Chess

给定两个序列 \(a, b\),根据以下规则,判断最后结果是否平局:

双方只从序列开头拿数字,假设序列 \(a, b\) 首元素分别为 \(x, y\),则:

  • 若 \(x > y\),则 \(x\) 被淘汰;
  • 若 \(x < y\),则 \(y\) 被淘汰;
  • 若 \(x = y\),\(x, y\) 同时被淘汰。

重复该过程,直到存在一方序列为空。

如果双方序列最终都为空,则平局,否则仍有剩余元素的一方获胜。

存在 \(q\) 次询问,每次单点修改后,询问最后结果是否平局。

\(|a|, |b|,q \leq 10^5, a_i, b_i \leq 10^5\)。

Sol:线段树,哈希

显然我们只关心最大值,并且如果平局,则两个序列最大值必须相同,记 \(a\) 中最大值第一次出现位置为 \(x\),\(b\) 中为 \(y\),则 \(a[1, x]\) 和 \(b[1, y]\) 最后一定会平局,我们不必关心淘汰的过程,因为 \(a_x\) 和 \(b_y\) 都是最大值且相同,所以结果是固定的。然后我们继续找 \(a[x + 1, |a|]\) 和 \(b[y + 1, |b|]\) 中的最大值,判断是否相同,然后重复该过程即可判断 \(a[1, |a|]\) 和 \(b[1, |b|]\) 是否平局。

不难发现,我们寻找的位置一定是后缀最大值的位置,即令 \(sufMax[i]\) 代表序列 \(a[i, n]\) 中的最大值,则我们关心的位置一定是 \(a_i = sufMax_i\) 的位置。

并且最终平局的话,\(a_{|a|},b_{|b|}\) 一定是必选的,观察后发现选择的位置一定是以序列末尾为起点的单调不减的子序列,记作 \(T\) 。例如 \(\{2, 3, 5, 4, 1,2, 1\}\),则选择的位置构成的子序列为 \(\{5, 4, 2, 1\}\),从右往左看单调不减。那么若最终平局,当且仅当 \(T_a = T_b\) 成立。

因为存在单点修改,我们只需要通过线段树分别维护子序列 \(T_a,T_b\) 的异或哈希即可,具体的:

以序列 \(a\) 为例,假设线段树上节点 \(i\) 所代表区间为 \(a[l, r]\),则该节点维护的信息为以 \(a[r]\) 为起点的 \(a[l, r]\) 中单调不减的子序列的哈希值,即 \(T_{a[l, r]}\) 所代表的哈希值,记作 \(shs[i]\);同时维护区间最大值 \(mx\)。

考虑左右儿子如何合并,即如何合并 \(T_{a[l, mid]}\) 和 \(T_{a[mid + 1,r]}\) 成 \(T_{a[l, r]}\),定义 \(ls\) 代表节点 \(i\) 的左儿子,\(rs\) 代表节点 \(i\) 的右儿子,则有:

  • 如果 \(mx[ls] < mx[rs]\),则 \(T_{a[l, r]} = T_{a[mid + 1, r]}\),即 \(shs[i] = shs[rs], mx[i] = mx[rs]\)。

  • 如果 \(mx[ls] \geq mx[rs]\),则 \(T_{a[l, r]}\) 中仍有部分元素在 \(T_{a[l, r]}\) 中,需要找到 \(a[l, mid]\) 中从右数起第一个 \(\geq mx[rs]\) 的位置 \(x\),则 \(T_{a[l, r]} = T_{a[l, x]} + T_{a[mid + 1, r]}\),即 \(shs[i] = \text{qry}(l, mid, mx[rs]) + shs[rs],mx[i] = mx[ls]\)。

    其中 \(\text{qry}(l, r, k)\) 代表 \(T_{a[l, x]}\) 的哈希值,其中 \(x\) 为 \(a[l, r]\) 中从右数起第一个 \(\geq k\) 的位置,具体的实现类似 P4198 楼房重建 通过线段树上二分实现:

    • 若 \(mx[rs] \geq k\),则返回 \(shs[i] - shs[rs] + \text{qry}(mid + 1, r, k)\)。注意并不是返回 \(shs[ls] + \text{qry}(mid + 1, r, k)\);
    • 若 \(mx[rs] < k\),则返回 \(\text{qry}(l, mid, k)\)。

由于合并的复杂度为 \(O(\log n)\),则总复杂度为 \(O(n\log ^2 n)\)。

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
using ull = unsigned long long;
const int N = 100010;
mt19937_64 rnd(time(0)); int n1, n2, q, a[N], b[N];
ull hs[N]; struct SegmentTree {
int mx[N << 2];
ull shs[N << 2]; // sum of hs
#define lson (id << 1)
#define rson (id << 1 | 1)
#define mid ((l + r) >> 1)
ull qry(int id, int l, int r, int k) {
if (mx[id] < k) return 0ULL;
if (l == r) return (mx[id] >= k ? shs[id] : 0ULL);
if (mx[rson] >= k) return qry(rson, mid + 1, r, k) + shs[id] - shs[rson];
else return qry(lson, l, mid, k);
}
void up(int id, int l, int r) {
mx[id] = max(mx[lson], mx[rson]);
shs[id] = qry(lson, l, mid, mx[rson]) + shs[rson];
}
void build(int id, int l, int r, int *a) {
if (l == r) {
mx[id] = a[l];
shs[id] = hs[a[l]];
return;
}
build(lson, l, mid, a), build(rson, mid + 1, r, a);
up(id, l, r);
}
void modify(int id, int l, int r, int x, int v) {
if (l == r) {
mx[id] = v;
shs[id] = hs[v];
return;
}
if (x <= mid) modify(lson, l, mid, x, v);
else modify(rson, mid + 1, r, x, v);
up(id, l, r);
}
#undef lson
#undef rson
#undef mid
} T[2]; void solve() {
for (int i = 1; i <= 100000; ++i) hs[i] = rnd();
cin >> n1;
for (int i = 1; i <= n1; ++i) {
cin >> a[i];
}
cin >> n2;
for (int i = 1; i <= n2; ++i) {
cin >> b[i];
}
T[0].build(1, 1, n1, a);
T[1].build(1, 1, n2, b);
cin >> q;
while (q--) {
int op, x, y; cin >> op >> x >> y;
if (op == 1) {
T[0].modify(1, 1, n1, x, y);
} else {
T[1].modify(1, 1, n2, x, y);
}
if (T[0].shs[1] == T[1].shs[1]) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
}
signed main(void) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int Test = 1;
// cin >> Test;
while (Test--) solve();
return 0;
}

L. Rooted Tree

一棵树,一开始仅有根节点 \(1\),每次操作会均匀随机选择一个叶子节点 \(u\) 并连接 \(M\) 个新节点作为 \(u\) 的儿子。询问操作 \(K\) 次后树上所有节点的深度和的期望值,答案对 \(10^9 + 9\) 取模。钦定 \(dep(1) = 0\)。\(M \leq 100, K \leq 10^7\)。

Sol:期望的线性性,概率,DP

根据期望的线性性,定义 \(T_i\) 代表第 \(i\) 次操作新增的叶子节点的集合,\(T\) 代表操作完 \(K\) 次后的节点集合,即 \(T = \{1\} + T_1 + T_2 + \dots + T_K\),则有:

\[E(\sum_{v\in T} dep(v)) = \sum_{i = 1}^K E(\sum_{v\in T_i}dep(v))
\]

定义 \(ans(i)\) 代表第 \(i\) 次操作新增的叶子节点的深度和的期望,即 \(ans(i) = E(\sum_{v\in T_i}dep(v))\)。

定义 \(cnt(i)\) 代表第 \(i\) 次操作后叶子节点个数,则有 \(cnt(i) = (M - 1) \times i + 1\),\(cnt(0) = 1\).

定义 \(f(i)\) 代表第 \(i\) 次操作后叶子节点的深度和的期望,即 \(f(i) = \sum_{j = 1}^{cnt_i} E(dep(v_j))\),其中 \(v_j\) 是第 \(i\) 次操作后的叶子节点,显然 \(f(0) = 0\)。

\(ans(i)\) 可以根据第 \(i - 1\) 次操作之后的叶子节点的深度得到,即:

\[\begin{align}
ans(i) &= \sum_{j = 1}^{cnt(i - 1)}\frac{1}{cnt(i - 1)}(E(dep_{v_j}) + 1) \times M \\
&= M (\frac{f(i - 1)}{cnt(i - 1)} + 1)
\end{align}
\]

\(f(i)\) 等于 \(f(i - 1)\) 加上新增的 \(ans(i)\),然后再减去减少的叶子节点的深度的期望和,即:

\[\begin{align}
f(i) &= f(i - 1) + ans(i) - \sum_{j = 1}^{cnt(i - 1)}\frac{1}{cnt(i - 1)}E(dep(v_j)) \\
&= f(i - 1) + ans(i) - \frac{f(i - 1)}{cnt(i - 1)}
\end{align}
\]

\(O(K + \log V)\) 预处理所有 \(cnt(i)\) 的逆元即可。

简单的来说令 \(prod[i] = \prod_{j = 1}^i cnt(j), iprod[i] = (\prod_{j = 1}^i cnt(j))^{-1}\)。

先 \(O(K)\) 得到 \(prod\) 后,通过快速幂得到 \(iprod[K]\) 后,根据 \(iprod[i] = iprod[i + 1] \times cnt(i + 1)\),可以 \(O(K)\) 递推出 \(iprod\)。所以 \((cnt(i))^{-1} = prod[i - 1] \times iprod[i]\)。

不难发现 \(M\) 与复杂度没有关系,本质上 \(M \leq 100\) 用来保证 \(cnt(i)\) 在模 \(10^9 + 9\) 意义下存在逆元。

时间复杂度:\(O(K)\)。

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
using ll = long long;
const int mod = 1e9 + 9; int add(int a, int b) {
int c = a + b;
if (c >= mod) c -= mod;
return c;
}
int sub(int a, int b) {
int c = a - b;
if (c < 0) c += mod;
return c;
}
int mul(int a, int b) {
ll c = 1ll * a * b;
if (c >= mod) c %= mod;
return c;
}
inline int ksm(int a, int b) {
int res = 1;
for (; b; b >>= 1) {
if (b & 1) {
res = 1ll * res * a % mod;
}
a = 1ll * a * a % mod;
}
return res;
} const int N = 10000010;
int f[N], cnt[N], inv[N], prod[N], iprod[N]; void solve() {
int M, K; cin >> M >> K;
cnt[0] = 1;
for (int i = 1; i <= K; ++i) cnt[i] = cnt[i - 1] + M - 1;
prod[0] = 1;
for (int i = 1; i <= K; ++i) prod[i] = mul(prod[i - 1], cnt[i]);
iprod[K] = ksm(prod[K], mod - 2);
for (int i = K - 1; i >= 1; --i) iprod[i] = mul(iprod[i + 1], cnt[i + 1]);
for (int i = 1; i <= K; ++i) inv[i] = mul(prod[i - 1], iprod[i]);
int ans = 0;
f[0] = 0;
for (int i = 1; i <= K; ++i) {
int res = mul(M, add(mul(f[i - 1], inv[i - 1]), 1));
ans = add(ans, res);
f[i] = 0;
f[i] = add(f[i], res);
f[i] = add(f[i], f[i - 1]);
f[i] = sub(f[i], mul(f[i - 1], inv[i - 1]));
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
return 0;
}

2023 CCPC 深圳的更多相关文章

  1. 视觉AI风口一触即发,虹软AI沙龙点金深圳

    7月26日,虹软AI沙龙在深圳湾科技生态园空间举办.AI沙龙是基于虹软视觉开放平台的开发者交流沙龙,旨在通过分享最新的实战案例,帮助开发者解决技术及落地难题,让技术更贴近实用场景. 本次活动中,深圳市 ...

  2. 一枚招聘信息——分期乐招页面重构/UI开发(8k-12k 深圳 经验1-3年 学历不限 全职)

    腾讯人创建的分期乐公司,急需页面重构人才若干枚,公司前景好,机会难得,有兴趣的速速 8k-12k 深圳 经验1-3年 学历不限 全职 公司网站: http://www.fenqile.com/ 职位诱 ...

  3. 深圳本土web前端经验交流

    群号:125776555  深圳本土web前端技术交流群 baidu tencent前端拒绝垃圾广告.吹水,欢迎讨论技术.跳槽经验期待您的加入 

  4. 活用UML-软件设计高手(深圳 2014年4月26-27日)

      我们将在深圳为您奉献高级技术课程”活用UML-软件设计高手“,首席专家张老师将会为您分享软件架构设计.数据库设计.用户体验设计及详细设计的最佳实践,帮助您成为优秀的软件设计师! 时间:2014.0 ...

  5. 敏捷遇上UML——软创基地马年大会(深圳站 2014-3-15)

    邀请函: 尊敬的阁下: 我们将在深圳为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战 ...

  6. 深圳 Maker Faire 2016 & Microsoft Booth

    首先,感谢Hackster.io和微软,因为发表在Hackster.io的项目<A fall detection system based on Arduino, Windows and Azu ...

  7. WinHEC 2015 深圳之行

    在上个月,本人有幸在MVP Team和MVP Lead的帮助下,参加了微软在深圳召开的WinHEC 2015大会. 在本次大会上,见证了微软和国内企业的合作,并且发布一些关于在Windows 10方面 ...

  8. 作为一名前端er,从武汉来到深圳三个月有感

    来到深圳已经三个月了,从最开始的担心自己的能力不够怕不能够在深圳这个互联网产品及其发达的城市立足下来,到现在已经慢慢地拾起了一丁点的信心了 (虽然还有很多知识是不够的.但是相当于之前我的,我是觉得我已 ...

  9. 2016 CCPC 东北地区重现赛

    1. 2016 CCPC 东北地区重现赛 2.总结:弱渣,只做出01.03.05水题 08   HDU5929 Basic Data Structure    模拟,双端队列 1.题意:模拟一个栈的操 ...

  10. 深圳楼市2007vs2016

    昨日新政,虽在预料之中,但心中未免有些感慨.今日在回深的火车上,突然由此让我回想起了2007年的那场深圳房价大溃败.忍不住写上一段供大家参考.前奏:2000年后的深圳楼市在2004年之前可以说是波澜不 ...

随机推荐

  1. OCR技术的昨天今天和明天!2023年最全OCR技术指南!

    OCR是一项科技革新,通过自动化大幅减少人工录入的过程,帮助用户从图像或扫描文档中提取文字,并将这些文字转换为计算机可读格式.这一功能在许多需要进一步处理数据的场景中,如身份验证.费用管理.自动报销. ...

  2. JAVA基础之5-函数式接口的实现

    之所以单独把这个列出来,是因为本人被一个源码给震撼了. 所以,本人目的是看看这个震撼实现,并模仿,最后把常规的实现也贴上,让读者可以看到相对完整的实现 注:本文代码基于JDK17 一.让人震撼的代码 ...

  3. EF Core – Library use EF

    前言 写 Library 有时候会用到 database, 会想用 EF 来维护. 比如 Identity, IdentityServer, OpenIddict, 这些 Library 都有使用到 ...

  4. docker 安装启动jenkins 以及问题剖析

    docker 安装启动jenkins 以及问题剖析   首先,你环境必须要有docker,我这里是自己本地虚拟机Vmware,我的虚拟机时linux centos7的 .如果你不知怎么安装虚拟机和命令 ...

  5. 《Spring Data JPA从入门到精通》内容简介、前言

    内容简介 本书以Spring Boot为技术基础,从入门到精通,由浅入深地介绍Spring Data JPA的使用.有语法,有实践,有原理剖析. 本书分为12章,内容包括整体认识JPA.JPA基础查询 ...

  6. TS体操类型学习记录

    Easy 1. Easy - 4 - Pick 从类型 T 中选出符合 K 的属性,构造一个新的类型 type MyPick<T, K extends keyof T> = { [key ...

  7. 在Windows平台使用源码编译和安装PyTorch3D指定版本

    最近在部署 SyncTalk 虚拟数字人项目时,需要安装很多依赖项,在执行到pip install --no-index --no-cache-dir pytorch3d -f https://dl. ...

  8. C# 的显示转换 *.Parse(string) Convert.ToInt32(double value)

    // 显式转换 (类型) /// (int)表示使用强制的显示转换,是一种类型转换,C#默认的整形是 int32 , /// 因此使用此方法转成int32 不遵循四舍五入,直截取整数部分 /// (i ...

  9. for 和双重 for 的区别?

    1. 内层的循环可以看作外层循环的语句 2. 外层循环执行 1 次 ,内层循环执行全部

  10. 推荐一款支持Vue3的管理系统模版:Vue-Vben-Admin

    近年来,随着前端技术的飞速发展,各类后台管理系统框架层出不穷.Vue 作为热门的前端框架,也有许多优秀的后台模板涌现.而 Vue-Vben-Admin,凭借其高效.灵活的架构设计和完善的功能体系,成为 ...