【2025.6.27 校內 NOI 模擬賽】總結(貪心, 容斥、組合計數, dsu on tree、 虛樹)

文章目錄

  • 時間安排
  • 反思
  • 題解
    • [六省聯考 2017] 期末考試(貪心, 枚舉)
    • [JSOI2019] 神經網絡(容斥, 組合計數, 樹背包)
    • [ZJOI2019] 語言(dsu on tree, 虛樹, 結論)

時間安排

  • 7 : 30 7:30 7:30 開題
  • 7 : 30 ? 7 : 35 7:30 - 7:35 7:30?7:35 看完 T 1 T1 T1 后嘗試推一下,發現好像前綴和一下就做完了??!然后就去寫了。
  • 7 : 55 7:55 7:55 調出來了,交上去過了。不到 30 m i n 30min 30min T 1 T1 T1。今天比較簡單啊。
  • 7 : 55 ? 8 : 10 7:55 - 8:10 7:55?8:10 理解了 T 2 T2 T2 的題意。剛開始覺得好復雜,后來忽然發現只有路徑上相鄰兩個元素在同一棵樹上才有限制,如果不在那么是任意的。感覺變得很套路了。
  • 8 : 10 ? 10 : 40 8:10 - 10:40 8:10?10:40:穩住心態,一點一點推式子,一步一步的將問題拆成小問題然后解決。中間有幾步意識到自己想的有點問題,但是大方向是對的所以也修過來了。然后終于寫完了,小樣例沒過!!雖然比較難調,但還是調過了。交上去,獲得高貴的 5 p t s 5pts 5pts
  • 10 : 40 ? 11 : 35 10:40 - 11:35 10:40?11:35 然后就去痛批 jsy 不給大樣例。但是他沒空所以就先去靜態差錯了。沒查出來,所以就去對拍。寫了個指數的暴力,交上去能過第一個點。先嘗試手造一些小數據。然后發現兩棵樹的都過了,大于兩棵樹的都 W A WA WA 了。思考后發現是每棵樹卷積合并的時候假了。然后就去修鍋,轉化成正確的模型后感覺自己不太會 n 2 n^2 n2 復雜度的??!!后來想了想發現容斥的思路可以優化到 O ( n 2 ) O(n^2) O(n2),改了一下交上去直接過了!!!
  • 11 : 35 ? 12 : 30 11:35 - 12:30 11:35?12:30 還有將近 1 h 1h 1h,想了想 T 3 T3 T3 的正解,發現沒出思路。然后寫了 60 p t s 60pts 60pts 暴力,在寫暴力的時候發現剛才想正解的方向都是錯的。但是時間也不允許再去思考和實現正解了。

最終得分: 100 + 100 + 60 = 260

反思

  • 調不出來時不要一直靜態差錯。有時候寫一個暴力是很快的。當你有小數據去調試時應該會比較快調對或者意識到你哪里錯了。
  • 思考問題除了特別有思路,否則最好不要直接去思考正解。可以從部分分入手,這樣會讓你的方向變得明確。

題解

[六省聯考 2017] 期末考試(貪心, 枚舉)

題面

分析:
唐題。發現不愉悅值只和成績最晚公布時間有關。直接枚舉最晚公布時間可以貪心的調整, O ( 1 ) O(1) O(1) 計算最小代價。復雜度線性。

CODE:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef __int128 Int;
const int N = 1e5 + 10;
LL A, B, C, st[N], stc[N], sb[N], sbc[N], res = 1e18;
int n, m, t[N], b[N], lim;
inline LL calc(int T) {Int ans = (Int)(1LL * T * stc[T] - st[T]) * C;if(ans > res) return res;LL ret = ans;if(1LL * m * T >= sb[lim]) ret += min(A, B) * (sb[lim] - sb[T] - (sbc[lim] - sbc[T]) * T);else ret += B * (sb[lim] - 1LL * m * T) + min(A, B) * (sb[lim] - sb[T] - (sbc[lim] - sbc[T]) * T - (sb[lim] - 1LL * m * T));return ret;
}
int main() {scanf("%lld%lld%lld", &A, &B, &C);scanf("%d%d", &n, &m);for(int i = 1; i <= n; i ++ ) {scanf("%d", &t[i]); lim = max(lim, t[i]);st[t[i]] += t[i]; stc[t[i]] ++;}for(int i = 1; i <= m; i ++ ) {scanf("%d", &b[i]); lim = max(lim, b[i]);sb[b[i]] += b[i]; sbc[b[i]] ++;}for(int i = 1; i <= lim; i ++ ) st[i] += st[i - 1], stc[i] += stc[i - 1];for(int i = 1; i <= lim; i ++ ) sb[i] += sb[i - 1], sbc[i] += sbc[i - 1];for(int T = 1; T <= lim; T ++ ) res = min(res, calc(T));cout << res << endl;return 0;
}

[JSOI2019] 神經網絡(容斥, 組合計數, 樹背包)

題面

題意:
給定 m m m 棵樹,第 i i i 棵樹有 k i k_i ki? 個結點。
除了這 m m m 棵樹的樹邊外,你要在任意兩個不在同一棵樹上的點 之間添加一條邊,得到一張聯通圖 G G G
你需要求出 G G G哈密頓回路 的數量。以第一棵樹的 1 1 1 號點為起點。

∑ i = 1 m k i ≤ 5000 , 1 ≤ m ≤ 300 , k i ≥ 1 \sum\limits_{i = 1}^{m}k_i \leq 5000, 1 \leq m \leq 300, k_i \geq 1 i=1m?ki?5000,1m300,ki?1

分析:
假設得到了一條以 1 1 1 為起點的哈密段回路 R R R R i R_i Ri? 表示第 i i i 個經過的點的編號。我們來考慮對 R R R 需要有什么限制。

發現對于路徑上相鄰的兩個點 R i , R i + 1 R_i, R_{i + 1} Ri?,Ri+1?,如果它們屬于不同的樹,那么這一對相鄰就沒有任何限制(兩棵樹之間的連邊是完全二分圖)。如果它們屬于同一棵樹,那么就必須要求 R i R_{i} Ri? R i + 1 R_{i + 1} Ri+1? 在樹上相鄰

那么我們將 R R R 分成若干極長連續段,每一段的點都在一棵樹上,發現 R R R 合法就等價于 每一段都對應樹上的一條有向路徑

這告訴我們不同的樹之間的限制是獨立的。我們分別對每一棵樹計算方案數,同時記錄劃分了多少段,然后不同的樹之間卷積合并即可。

對一棵樹相當于要求 將它劃分成若干不交路徑(每個點恰好屬于一條路徑)的方案數。這是一個很經典的問題, d p dp dp 狀態只需要記錄子樹內已經劃分了多少條路徑,根是否在一條半鏈 即可。轉移就是經典的樹背包卷積,復雜度 O ( k i 2 ) O(k_i^2) O(ki2?)

一個小細節就是長度 ≥ 2 \geq 2 2 的路徑有兩個方向,但是長度等于 1 1 1 的路徑只有一個方向,所以不太好求出路徑條數之后再考慮方向對方案數的貢獻。這個只要在 d p dp dp 時每產生一條路徑就把系數乘進去即可。

對于第一棵樹也需要特殊處理!因為我們固定了 第一棵樹的 1 1 1 號點為起點,所以 1 1 1 號點所在的路徑上 1 1 1 必須作為端點,并且這條路徑不能調轉方向。這個只需要特殊處理一下轉移即可。

還有一個問題:我們要求的 回路,然后已經固定了第一段是第一棵樹的 1 1 1 所在路徑。但是我們不知道最后一段是什么(還需要考慮后面樹提供的段)。如果最后一段也是第一棵樹的一條路徑,那么需要保證最后一個點是能到 1 1 1 的。

這個處理起來比較麻煩:只需要拿 不限制 1 1 1 提供最后一段 的方案數 減去 欽定 1 1 1 提供最后一段 的方案數,加上 欽定 1 1 1 提供最后一段,并且最后一段要合法 的方案數即可。怎么欽定提供最后一段呢?將后面的段看作 插入前面段的間隔中,那么只要刪掉最后一個間隔就能保證它提供最后一段了。怎么保證最后一段合法呢?發現第一段和最后一段恰好就構成了一條 不要求 1 1 1 在端點的包含 1 1 1 的路徑。那么我們求出這樣的路徑劃分數量,然后把 1 1 1 所在的路徑拆成兩條即可,注意此時最后一段也不能調轉方向

除了第一個樹,后面的都是相同的。考慮現在還有一個限制,就是 一棵樹分成的段之間不能相鄰。怎么處理這個呢?

容斥這個限制:對于第一棵樹,相當于提供了若干空,你可以往這些空里面插其它樹形成的段,但是一定要把這些空都插有。我們欽定 i i i 個空最終沒被插,然后乘上 ( ? 1 ) i (-1)^i (?1)i 的容斥系數,就變成有若干空,任意往里面插了。對于后面的樹也類似:假設形成了 x x x 段,那么欽定了 t t t 段不合法后相當于就變成了 x ? t x - t x?t 個段,然后就是一個 x 1 + x 2 + . . . + x x ? t = c x_1 + x_2 + ... + x_{x - t} = c x1?+x2?+...+xx?t?=c x i ≥ 0 x_i \geq 0 xi?0 的問題,可以組合數 O ( 1 ) O(1) O(1) 計算方案,然后新增的空位數量恒定為 x ? t x - t x?t。注意這里枚舉樹的段和欽定若干不合法是 O ( k i 2 ) O(k_i^2) O(ki2?),然后這一部分要和與之前的卷積分開枚舉,復雜度就是 O ( ( ∑ k i ) 2 ) O((\sum k_i)^2) O((ki?)2)

這樣就做完了。時空復雜度 O ( ( ∑ k i ) 2 ) O((\sum k_i)^2) O((ki?)2)

CODE:

#include<bits/stdc++.h>
#define pb emplace_back
using namespace std;
const int N = 5010;
typedef long long LL;
const LL mod = 998244353;
int m, n, sum, sz[N];
vector< int > E[N];
LL C[N][N], mi[N], fac[N], h[2][N], f[2][N][N], g[N][N], tg[N], tf[2][N]; // h[i][j] 表示考慮到了第 i 棵樹,還有 j 個空位可以插的方案數。  f[x][i] 表示 x 在一條半鏈上, g[x][i] 表示在一條完整的鏈上
void dfs(int x, int fa, int p) { // 求一遍正常的鏈劃分if(x == 1 && p == 1) {f[0][x][0] = 2; f[1][x][0] = 1;}else {f[0][x][0] = f[1][x][0] = 1; g[x][1] = 1;} sz[x] = 1;for(auto v : E[x]) {if(v == fa) continue;dfs(v, x, p); for(int i = 0; i <= sz[x] + sz[v]; i ++ ) tg[i] = tf[0][i] = tf[1][i] = 0;for(int i = 0; i <= sz[x]; i ++ ) {for(int j = 0; j <= sz[v]; j ++ ) {tg[i + j] = (tg[i + j] + g[x][i] * g[v][j] % mod) % mod; // g * g -> gtg[i + j + 1] = (tg[i + j + 1] + f[1][x][i] * f[1][v][j] % mod * ((x == 1 && p == 1) ? 1 : 2) % mod) % mod; // f * f -> gtf[0][i + j] = (tf[0][i + j] + f[0][x][i] * g[v][j] % mod) % mod; // f * g -> ftf[1][i + j] = (tf[1][i + j] + f[1][x][i] * g[v][j] % mod) % mod; // f * g -> ftf[1][i + j] = (tf[1][i + j] + f[0][x][i] * f[1][v][j] % mod) % mod; // f * f -> f}}for(int i = 0; i <= sz[x] + sz[v]; i ++ ) f[0][x][i] = tf[0][i], f[1][x][i] = tf[1][i], g[x][i] = tg[i];sz[x] += sz[v];}
}
LL tmp[N]; 
inline LL sign(int x) {return (x & 1) ? mod - 1 : 1;}
inline void solve(int p, int l) { // 處理第 p 棵樹for(int i = 0; i <= n; i ++ ) for(int j = 0; j <= n; j ++ ) f[0][i][j] = f[1][i][j] = g[i][j] = 0;dfs(1, 0, p);// 現在 g[x][i] 表示把 x 的子樹劃分成 i 條鏈, 并且長度 >= 2 的要乘上 2 的系數if(p == 1) { // 特別處理 T_1, 這個還需要容斥一下保證滿足段之間不相鄰的限制, 容斥完就變成這些段任意了// 思路是總的 - 有 1 段在末尾的 + 有 1 段在末尾并且合法的。 for(int i = 1; i < n; i ++ ) tmp[i + 1] = g[1][i] * fac[i - 1] % mod;for(int i = 0; i <= n; i ++ ) f[1][1][i] = g[1][i] = 0;f[1][1][0] = 1, g[1][1] = 1; int nsz = 1;for(auto v : E[1]) {for(int i = 0; i <= nsz + sz[v]; i ++ ) tf[1][i] = tg[i] = 0;for(int i = 0; i <= nsz; i ++ ) {for(int j = 0; j <= sz[v]; j ++ ) {tf[1][i + j] = (tf[1][i + j] + f[1][1][i] * g[v][j] % mod) % mod;tg[i + j] = (tg[i + j] + g[1][i] * g[v][j] % mod) % mod;tg[i + j + 1] = (tg[i + j + 1] + f[1][1][i] * f[1][v][j] % mod) % mod; // 注意這里不能乘 2}}for(int i = 0; i <= nsz + sz[v]; i ++ ) f[1][1][i] = tf[1][i], g[1][i] = tg[i];nsz += sz[v];}for(int i = 1; i <= n; i ++ ) { // 枚舉段數//~ cout << "RRR" << i << ' ' << g[1][i] << endl;for(int j = 0; j <= i - 1; j ++ ) { // 欽定 i - 1 個里面有 j 個最后沒被插, 剩余隨意h[1][i - j] = (h[1][i - j] + g[1][i] * fac[i - 1] % mod * sign(j) % mod * C[i - 1][j] % mod) % mod;}// 欽定在末尾的for(int j = 0; j <= i - 1; j ++ ) {h[1][i - 1 - j] = (h[1][i - 1 - j] + g[1][i] * fac[i - 1] % mod * (mod - 1) % mod * sign(j) % mod * C[i - 1][j] % mod) % mod;}// 合法的欽定在末尾的for(int j = 0; j <= i - 1; j ++ ) {h[1][i - 1 - j] = (h[1][i - 1 - j] + tmp[i] * sign(j) % mod * C[i - 1][j] % mod) % mod; // tmp[i] 表示有 i 段, 并且末尾與開頭合法}}}else { // 這個就簡單了, 只需要看 g[1][i], 然后插板即可// 現在 h 的含義是 h_i 表示有 i 個空, 不要求最后它們都被插 for(int i = 1; i <= sz[1]; i ++ ) tmp[i] = 0;for(int i = 1; i <= sz[1]; i ++ ) { // g[1][i]LL v = g[1][i] * fac[i] % mod; // i 個元素// 欽定一些限制不成立for(int j = 0; j <= i - 1; j ++ ) {// 那么就合并成了 i - j 個元素了tmp[i - j] = (tmp[i - j] + v * C[i - 1][j] % mod * sign(j) % mod) % mod;}}for(int i = 1; i <= sz[1]; i ++ ) { // 只關心最后剩下幾個元素, 加入它們一定會多 i 個空位for(int j = 1; j <= l; j ++ ) {h[p & 1][j + i] = (h[p & 1][j + i] + h[p - 1 & 1][j] * tmp[i] % mod * C[i + j - 1][j - 1] % mod) % mod;}}for(int i = 0; i <= l; i ++ ) h[p - 1 & 1][i] = 0;}
}
int main() {mi[0] = 1; for(int i = 1; i < N; i ++ ) mi[i] = (mi[i - 1] * 2) % mod;fac[0] = 1; for(int i = 1; i < N; i ++ ) fac[i] = fac[i - 1] * i % mod;for(int i = 0; i < N; i ++ ) for(int j = 0; j <= i; j ++ ) if(!j) C[i][j] = 1;else C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;scanf("%d", &m); int now = 0;for(int i = 1; i <= m; i ++ ) {scanf("%d", &n); sum += n;for(int j = 1; j <= n; j ++ ) E[j].clear();for(int j = 1; j < n; j ++ ) {int u, v; scanf("%d%d", &u, &v); E[u].pb(v); E[v].pb(u);}solve(i, now); // 特殊處理 T_1now += n;}LL res = 0;for(int i = 0; i <= sum; i ++ ) res = (res + h[m & 1][i]) % mod;cout << res << endl;return 0;
}

[ZJOI2019] 語言(dsu on tree, 虛樹, 結論)

題面

題意:
給定 一棵 n n n 個點的樹和 m m m 條路徑 ( s i , t i ) (s_i, t_i) (si?,ti?),其中第 i i i 條路徑上的點都 具有 i i i這種顏色。
對一個點 x x x,它能 訪問 y y y 當且僅當 ( x , y ) (x, y) (x,y) 路徑上的點都具有某種顏色 c c c
你需要求出所有點對 ( u , v ) (u, v) (u,v) 的數量,滿足 u < v u < v u<v u u u 能訪問 v v v

1 ≤ n , m ≤ 1 0 5 1 \leq n, m \leq 10^5 1n,m105

分析:
考慮一個暴力怎么寫:先來計算有序對的數量,最后 / 2 /2 /2 就是無序對的數量。對每個 x x x 分別計算它能訪問多少個 y y y,可以將所有 經過 x x x 的路徑 拿出來,把路徑上的點涂黑,那么黑點的數量減 1 1 1 就是 x x x 能訪問的點數。

發現暴力等價于枚舉 x x x,然后保留所有經過 x x x 的路徑的端點后建出 虛樹,虛樹的邊數就是 x x x 的答案。

有經典結論:任意點集的虛樹周長等于按照 d f s dfs dfs 序將點集中的點排序后,相鄰兩個點的距離之和(認為最后一個和第一個也是相鄰的)。
這里的周長就是虛樹的邊數。

那么我們只要能維護出所有經過 x x x 的路徑的端點,按照 d f s dfs dfs 序排序后的有序集合就可以支持加點,刪點后快速更新答案

將一條路徑看作在兩個端點處加入,在 l c a lca lca 處刪除。然后直接上 d s u dsu dsu,開一個 s e t set set 維護當前還保留的路徑端點,每次往里 加入,刪除點,增量修改答案。那么一個點上的所有路徑信息顯然會被處理 log ? n \log n logn 次,每次加入/刪除一個點復雜度 O ( log ? n ) O(\log n) O(logn),總復雜度就是 O ( m log ? 2 n ) O(m\log^2 n) O(mlog2n)

代碼很好寫,沒啥細節。

CODE:

// dsu on tree 就是倆log
#include<bits/stdc++.h>
#define pb emplace_back
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, m, s[N], t[N];
int dep[N], sz[N], big[N], fat[N][18], dfn[N], L[N], R[N], dfc, ID[N];
int cnt[N];
LL res, ans; // ans 表示當前維護的虛樹大小
set< int > S; // 按照 dfn 排序
vector< int > E[N];
vector< int > Ad[N], De[N];
void dfs0(int x, int fa) {fat[x][0] = fa; for(int i = 1; i <= 17; i ++ ) fat[x][i] = fat[fat[x][i - 1]][i - 1];dep[x] = dep[fa] + 1; sz[x] = 1;for(auto v : E[x]) {if(v == fa) continue;dfs0(v, x); sz[x] += sz[v];if(sz[v] > sz[big[x]]) big[x] = v;}
}
void dfs1(int x, int fa) {dfn[x] = L[x] = ++ dfc; ID[dfc] = x;if(big[x]) dfs1(big[x], x);for(auto v : E[x]) {if(v == fa || v == big[x]) continue;dfs1(v, x);}R[x] = dfc;
}
inline int lca(int x, int y) {if(dep[x] < dep[y]) swap(x, y);for(int i = 17; i >= 0; i -- ) if(dep[fat[x][i]] >= dep[y]) x = fat[x][i];if(x == y) return x;for(int i = 17; i >= 0; i -- )if(fat[x][i] != fat[y][i]) x = fat[x][i], y = fat[y][i];return fat[x][0];
}
inline int dis(int x, int y) {return dep[x] + dep[y] - 2 * dep[lca(x, y)];}
inline LL calc(int x) { auto it = S.lower_bound(x);it ++;if(it == S.end()) it = S.begin();int nxt = (*it);return dis(ID[nxt], ID[x]);
}
inline void add(int x) {cnt[x] ++;if(cnt[x] != 1) return ;else {if(S.empty()) S.insert(dfn[x]);else { // 找到上一個auto it = S.lower_bound(dfn[x]);if(it == S.begin()) {it = S.end(); it --;}else it --;int o = (*it);ans -= calc(o);S.insert(dfn[x]);ans += calc(dfn[x]) + calc(o);}}
}
inline void del(int x) {cnt[x] -= 2; if(cnt[x] != 0) return ;if(S.size() == 1) S.erase(dfn[x]);else {		auto it = S.find(dfn[x]);if(it == S.begin()) {it = S.end(); it --;}else it --;int o = (*it);ans -= calc(dfn[x]) + calc(o);S.erase(dfn[x]);ans += calc(o);}
}
inline void Add(int x) {for(auto v : Ad[x]) add(s[v]), add(t[v]);} // 加入路徑端點
inline void Del(int x) {for(auto v : De[x]) del(s[v]), del(t[v]);} // 刪除路徑端點
void dfs2(int x, int fa, bool keep) { // dus on treefor(auto v : E[x]) {if(v == fa || v == big[x]) continue;dfs2(v, x, false);}if(big[x]) dfs2(big[x], x, true);for(auto v : E[x]) { // 加入輕子樹if(v == fa || v == big[x]) continue;for(int i = R[v]; i >= L[v]; i -- ) Add(ID[i]);for(int i = R[v]; i >= L[v]; i -- ) Del(ID[i]);}Add(x); res += ans; Del(x);if(!keep) {ans = 0; S.clear();for(int i = L[x]; i <= R[x]; i ++ ) for(auto v : Ad[ID[i]]) cnt[s[v]] = cnt[t[v]] = 0;}
}
int main() {scanf("%d%d", &n, &m);for(int i = 1; i < n; i ++ ) {int u, v; scanf("%d%d", &u, &v);E[u].pb(v); E[v].pb(u);}dfs0(1, 0);dfs1(1, 0);for(int i = 1; i <= m; i ++ ) {scanf("%d%d", &s[i], &t[i]);int lc = lca(s[i], t[i]);Ad[s[i]].pb(i); Ad[t[i]].pb(i);De[lc].pb(i);}dfs2(1, 0, 0);cout << res / 4 << endl;return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86446.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86446.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86446.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實際前端開發中,常用指令的封裝

實際前端開發中&#xff0c;常用指令的封裝 全局指令處理步驟main.ts指令目錄結構src/directives/index.ts 一、輸入框空格禁止指令1、指令文件clearSpace.ts2、指令使用 全局指令處理步驟 main.ts import { createApp } from "vue"; import App from "./App.…

鴻蒙OH南向開發 輕量系統內核(LiteOS-M)【異常調測】

基本概念 OpenHarmony LiteOS-M提供異常接管調測手段&#xff0c;幫助開發者定位分析問題。異常接管是操作系統對運行期間發生的異常情況進行處理的一系列動作&#xff0c;例如打印異常發生時異常類型、發生異常時的系統狀態、當前函數的調用棧信息、CPU現場信息、任務調用堆棧…

算法-堆排序

文章目錄 整體架構流程技術細節小結 整體架構流程 大頂推&#xff1a;是構建一個完整的二叉樹 大頂推&#xff1a;即父節點的值大于左右子樹的值。 循環構建大頂推 在給定的數組&#xff0c;既可以明確樹的高度。 在循環的時候&#xff0c;構建樹的高度從lgn至0。即從堆低往堆…

【鴻蒙HarmonyOS Next App實戰開發】二維碼生成技術實現與解析

隨著移動應用開發中對便捷交互體驗的需求日益增長&#xff0c;二維碼作為信息傳遞的重要載體&#xff0c;其生成與使用變得越來越普遍。本文將基于鴻蒙HarmonyOS應用開發框架&#xff0c;詳細介紹如何實現一個功能完備的二維碼生成器&#xff0c;并附上完整代碼解析。 注意該實…

1 Studying《Is Parallel Programming Hard》6-9

目錄 Chapter 6 Partitioning and Synchronization Design 6.1 分區練習 6.2 設計準則 6.3 同步粒度 6.4 并行快速路徑 6.5 超越黨派分歧 6.6 分區、并行和優化 Chapter 7 Locking 7.1 活命 7.2 鎖的類型 7.3 鎖定實施問題 7.4 基于鎖的存在性保證 7.5 鎖定&a…

Java練習題精選16-20

Java練習題精選16-20 一、第十六題二、第十七題三、第十八題四、第十九題五、第二十題一、第十六題 現有一個存放學生成績的數組{66, 77, 88, 99},要求將該數組正序輸出每個下標所對應的元素。 public class Test {public static void main(String[] args) {int<

新能源知識庫(68)汽車電鍍與蒸汽

汽車電鍍是提升零部件耐磨性、抗腐蝕性和美觀性的關鍵工藝&#xff0c;其流程根據基材&#xff08;金屬或塑料&#xff09;和部件功能需求有所差異。 汽車電鍍是以 基材特性和 功能需求為導向的精密工藝&#xff1a; ?金屬件?&#xff1a;核心流程為 ?除油→酸洗→電鍍→鈍…

Veo 3 視頻生成大模型完整操作教程(2025)

隨著 AI 多模態能力的飛躍&#xff0c;Google DeepMind 發布的 Veo 3 成為了生成視頻領域的一顆重磅炸彈。它不僅能夠根據文本生成高質量的視頻畫面&#xff0c;還能同步生成對白、背景音和環境音&#xff0c;是目前最接近真正“AI 導演”的大模型。 本文將帶你詳細了解 Veo 3…

10【認識文件系統】

1 認識硬件——磁盤 1.1 物理構成 磁盤是計算機中唯一的機械設備&#xff0c;同時也是一種外部存儲設備&#xff08;外設&#xff09;。早期的計算機通常配備的是機械硬盤&#xff08;HDD&#xff09;&#xff0c;依靠磁頭和盤片的機械運動來進行數據的讀寫。但隨著用戶對計算…

Windows命令連接符的安全風險分析與防御策略

1. 命令連接符簡介 在 Windows 的命令行環境&#xff08;CMD/PowerShell&#xff09;中&#xff0c;命令連接符用于在同一行執行多個命令&#xff0c;提高效率。然而&#xff0c;攻擊者常利用這些符號構造惡意命令&#xff0c;繞過安全檢測或執行多階段攻擊。 常見命令連接符…

大屏可視化制作指南

一、大屏可視化概述 &#xff08;一&#xff09;概念 大屏可視化是指通過大屏幕展示復雜數據的視覺呈現形式&#xff0c;它借助圖形、圖表、地圖等元素&#xff0c;將海量數據以直觀易懂的方式呈現出來&#xff0c;幫助用戶快速理解數據背后的含義和價值。 &#xff08;二&a…

Halcon ——— OCR字符提取與多類型識別技術詳解

工業視覺實戰&#xff1a;OCR字符提取與多類型識別技術詳解 在工業自動化領域&#xff0c;OCR字符提取是產品追溯、質量控制和信息讀取的核心技術。本文將深入解析Halcon中OCR字符提取的全流程&#xff0c;重點解釋核心算子參數&#xff0c;并提供完整的工業級代碼實現。 一、O…

嵌入式項目:基于QT與Hi3861的物聯網智能大棚集成控制系統

關鍵詞&#xff1a;MQTT、物聯網、QT、網絡連接、遠程控制 一、系統概述 本系統是一套完整的智能大棚監控解決方案&#xff0c;由兩部分構成&#xff1a; 基于Hi3861的嵌入式硬件系統&#xff08;負責環境數據采集和設備控制&#xff09;基于Qt開發的跨平臺控制軟件&#xf…

揭開 Git 裸倉庫的神秘面紗:`git clone --mirror` 詳解與使用指南

大家好&#xff01;在使用 Git 進行版本控制時&#xff0c;我們最熟悉的莫過于那些帶有工作目錄的本地倉庫了——我們在里面編輯文件、提交代碼&#xff0c;然后推送到遠程倉庫。但有時候&#xff0c;我們可能會遇到一種特殊的倉庫&#xff1a;裸倉庫&#xff08;Bare Reposito…

opensuse安裝rabbitmq

您好&#xff01;安裝 RabbitMQ 消息隊列是一個非常棒的選擇&#xff0c;它是許多現代應用架構中的核心組件。 在 openSUSE Tumbleweed 上安裝 RabbitMQ 主要有兩種流行的方式&#xff1a;一種是使用系統的包管理器 zypper&#xff0c;另一種是使用 Docker 容器。我將為您詳細…

超詳細YOLOv8/11圖像菜品分類全程概述:環境、數據準備、訓練、驗證/預測、onnx部署(c++/python)詳解

文章目錄 一、環境準備二、數據準備三、訓練四、驗證與預測五、模型部署 一、環境準備 我的都是在Linux系統下&#xff0c;訓練部署的&#xff1b;模型訓練之前&#xff0c;需要配置好環境&#xff0c;Anaconda、顯卡驅動、cuda、cudnn、pytorch等&#xff1b; 參考&#xff1…

JUC:4.線程常見操作與兩階段終止模式

在線程中&#xff0c;wait()、join()、sleep()三個方法都是進行阻塞的方法。對應可以使用interrupt()方法進行打斷&#xff0c;被打斷后線程會拋出打斷異常&#xff0c;但是不會修改IsInterrupt&#xff0c;也就是此時去調用IsInterrupted()方法后獲得的實際上是false。 而當線…

分布式session解決方案

在實際項目中&#xff0c;前臺代碼部署在nginx中&#xff0c;后臺服務內嵌了tomcat運行在不同的節點中&#xff0c;常見的架構如下&#xff1a; 在上述架構中&#xff0c;nginx轉發前臺請求&#xff0c;第一次登錄后&#xff0c;將用戶登錄信息寫入到一臺服務session中&#xf…

UDP 緩沖區

UDP 有接收緩沖區&#xff0c;沒有發送緩沖區 引申問題 1、為什么沒有發送緩沖區&#xff1f; 直接引用原文 “因為 UDP 是不可靠的&#xff0c;它不必保存應用進程的數據拷貝&#xff0c;因此無需一個真正的發送緩沖區” 2、沒有發送緩沖區的情況下&#xff0c;sendto 的數…

解密 C++ 中的左值(lvalue)與右值(rvalue)的核心內容

在 C 中&#xff0c;表達式&#xff08;expression&#xff09; 可以被歸類為左值或右值。最簡單的理解方式是&#xff1a; 左值&#xff08;lvalue&#xff09;&#xff1a; 能放在賦值號 左邊的表達式&#xff0c;通常表示一個有名字、有內存地址、可以持續存在的對象。你可…