当前位置: 首页 > news >正文

4.16 AT好题选做

文章目录

  • 前言
  • [ARC103D] Distance Sums(确定树的形态,trick)
  • [AGC062B] Split and Insert(区间 d p dp dp)
  • [AGC012E] Camel and Oases(状压,可行性dp转最优性dp)
  • [ARC094D] Normalization(trick,转化)
  • [ARC125F] Tree Degree Subset Sum(结论,adhoc)
  • [AGC049E] Increment Decrement(slope trick, 计数技巧,神仙题)

前言

学长给我们挑了几道AT的思维题,码量都很小,但是思维难度较高。
马拉松的时候过了前三道,后三道的确是人类智慧。记录一下做法。

[ARC103D] Distance Sums(确定树的形态,trick)

题意:
给你一个长度为 N N N 的正整数数组 D i D_i Di保证 D i D_i Di 互不相同。你需要构造一棵 N N N 个点的树,树的边权都为 1 1 1, 满足 i i i 号点到其它所有点的距离和恰好为 D i D_i Di。如果不存在输出 − 1 -1 1,否则输出所有的边 ( u i , v i ) (u_i, v_i) (ui,vi)

2 ≤ N ≤ 1 0 5 , 1 ≤ D i ≤ 1 0 12 2 \leq N \leq 10^5, 1\leq D_i \leq 10^{12} 2N105,1Di1012保证 D i D_i Di 互不相同

分析:
关键点在于怎样运用 D i D_i Di 互不相同。
首先容易看出,如果能构造满足条件的树,那么这棵树一定只有一个 重心,并且重心的编号就是 D i D_i Di 最小的 i i i
考虑以这个重心为根确定树的形态:
从根往下确定是比较难做的,我们考虑对于每个点确定它的父亲,这在许多交互题里是常见的套路。设任意一个点 x x x 的父亲为 y y y,一定满足 D y < D x D_y < D_x Dy<Dx,这是因为在以重心为根的情况下向子树里递归距离的增量总是大于减量的。那么我们将 D i D_i Di 从小到大排序后倒着确定每个点 i i i 的父亲,此时一定确定 i i i 子树里所有的点。
那么同时知道 i i i子树大小 D i D_i Di,是很容易确定 i i i 父亲 j j j D j D_j Dj 的。考虑从 j j j 递归到 i i i 时,增量为 n − s z i n - sz_i nszi,减量为 s z i sz_i szi,因此有 D j + n − 2 × s z i = D i D_j + n - 2 \times sz_i = D_i Dj+n2×szi=Di D j = D i + 2 × s z i − n D_j = D_i + 2 \times sz_i - n Dj=Di+2×szin,那么开一个 m a p map map 就能知道 D j D_j Dj 对应的编号了。
坑点在于还原出树的形态也未必能对应上 D i D_i Di 数组,我们还需要验证一下重心 x x x 到其它点的距离和是否等于 D x D_x Dx
复杂度 O ( n ) O(n) O(n)
CODE:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
unordered_map< LL, int > idx;
int n, odr[N], fat[N], sz[N];
LL d[N];
inline bool cmp(int x, int y) {return d[x] < d[y];}
int main() {scanf("%d", &n);for(int i = 1; i <= n; i ++ ) {scanf("%lld", &d[i]);odr[i] = i;idx[d[i]] = i;}sort(odr + 1, odr + n + 1, cmp);for(int i = 1; i <= n; i ++ ) sz[i] = 1;LL res = 0;for(int i = n; i > 1; i -- ) { // 倒着考虑 int o = odr[i];LL v = d[o] - (n - 2 * sz[o]);if(!idx[v] || v >= d[o]) {puts("-1"); return 0;}sz[idx[v]] += sz[o], fat[o] = idx[v]; res += 1LL * sz[o];}if(res != d[odr[1]]) {puts("-1"); return 0;}for(int i = 1; i <= n; i ++ ) {if(fat[i]) printf("%d %d\n", fat[i], i);}return 0;
}

[AGC062B] Split and Insert(区间 d p dp dp)

题意:
给你一个长度为 N N N 的排列 A A A,初始时 A i = i A_i = i Ai=i。你可以进行 K K K 轮操作,每一轮你可以选择排列末尾的 k i k_i ki 个数字,需要满足 k i ∈ [ 0 , n − 1 ] k_i \in [0, n - 1] ki[0,n1]。 然后将排列变成 A ′ A' A, 需要满足 A 1 … n − k i A_{1 \dots n - k_i} A1nki A ′ A' A A ′ A' A 的一个 子序列 A n − k i + 1 … n A_{n - k_i + 1 \dots n} Anki+1n A ′ A' A 的一个子序列。
你的目标是 K K K 轮操作后将排列变成 P P P,你的花费为 ∑ i = 1 K C i × k i \sum\limits_{i = 1}^{K}C_i \times k_i i=1KCi×ki。其中 P P P 为给定排列, C C C 为给定的数组。问你能否完成目标,如果不能输出 − 1 -1 1,否则输出最小花费。

2 ≤ N ≤ 100 , 1 ≤ K ≤ 100 , 1 ≤ C i ≤ 1 0 9 2 \leq N \leq 100, 1 \leq K \leq 100, 1 \leq C_i \leq 10^9 2N100,1K100,1Ci109

分析:
首先令 p o s P i = i pos_{P_i} = i posPi=i,然后将 A i ← p o s i A_i \gets pos_i Aiposi,那么目标变成了将 A A A 排序。
来考虑操作和排序有什么关系:发现如果有两个极长有序段,那么操作后面的连续段可以把它与前面的合并为一个极长有序段

这启发我们先将原排列划分成若干个 极长有序段 考虑:
首先有一个容易想到的事情是,每次操作一定是末尾的若干完整段,不会在某一个段内断开。
感性证明:如果第 i i i 次在某一段内断开,那么下次操作剩下这一部分时的代价系数 C j C_j Cj 如果小于 C i C_i Ci,显然可以将原来那一部分放到这次操作,否则可以将剩下这一部分在上次操作,答案会变得更优。
那么目标就变成了最优化合并过程,使得最后合并成一段。

每次操作的末尾几段应该怎么与前面合并?
首先合并后这几段不可能存在两段同时出现在一个有序段里,因为相对顺序不能改变。所以它们只有分别找前面的一段合并才有用。
但是你会发现将这几段合并到最靠前的段里好像未必最优,因为可能存在后面某轮 C i C_i Ci 比较小,我想把此时最后一段合并到第一段,那么此时最后一段应该越多越优。
但是能够发现 这些段的第一段一定是合并到开头段 的。证明感性理解吧。
那么由于 C i C_i Ci 的系数是 数量,会发现此时选中段与前面段可以 独立考虑 了!!可以认为 两部分在后面的轮次中都需要将所有段合并到这一部分的开头段。并且容易证明不存在更优秀的策略了。

因此直接区间 d p dp dp 即可:设 d p l , r , k dp_{l, r, k} dpl,r,k 表示从第 k k k 轮开始往后的轮次中,将 l ∼ r l \sim r lr 的极长连续段合并成一段的最小花费。转移枚举第 k k k 次选中的后缀段即可。复杂度 O ( n 3 K ) O(n^3K) O(n3K)

CODE:

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
typedef long long LL;
int n, K, p[N], pos[N], a[N], tot;
LL c[N], dp[N][N][N], sum[N];
int main() {scanf("%d%d", &n, &K);for(int i = 1; i <= K; i ++ ) scanf("%lld", &c[i]);for(int i = 1; i <= n; i ++ ) {scanf("%d", &p[i]); pos[p[i]] = i;}for(int i = 1; i <= n; i ++ ) p[i] = pos[i]; // 现在要把 p[i] 排序for(int i = 1; i <= n; ) {int j = i + 1;while(j <= n && p[j] > p[j - 1]) j ++;a[++ tot] = j - i;i = j;}for(int i = 1; i <= tot; i ++ ) sum[i] = sum[i - 1] + a[i];memset(dp, 0x3f, sizeof dp);for(int i = 0; i <= K + 1; i ++ ) {for(int j = 1; j <= tot; j ++ ) {dp[j][j][i] = 0;}}for(int len = 2; len <= tot; len ++ ) {for(int L = 1; L + len - 1 <= tot; L ++ ) {int R = L + len - 1;for(int k = K; k >= 1; k -- ) {			dp[L][R][k] = min(dp[L][R][k], dp[L][R][k + 1]); // 不动for(int mid = L + 1; mid <= R; mid ++ ) { // [mid, R] 移动  dp[L][R][k] = min(dp[L][R][k], dp[L][mid - 1][k + 1] + dp[mid][R][k + 1] + (sum[R] - sum[mid - 1]) * c[k]);}}}}if(dp[1][tot][1] > 1e12) puts("-1");else printf("%lld\n", dp[1][tot][1]);return 0;
}

[AGC012E] Camel and Oases(状压,可行性dp转最优性dp)

题意:
给你数轴上的 N N N 个点 x 1 … x N x_1 \dots x_N x1xN,保证 − 1 0 9 ≤ x 1 < x 2 < ⋯ < x N ≤ 1 0 9 -10^9 \leq x_1 < x_2 < \dots < x_N \leq 10^9 109x1<x2<<xN109。你需要对某个点 i i i 判断以 x i x_i xi 为起点能否按照以下方式遍历所有点:

  • 初始时有一个油量上限 V V V V V V 开始时给定。开始时有 V V V 升油。
  • 你可以从当前点 a a a 走路到一个点 b b b,满足 ∣ x a − x b ∣ ≤ V ′ |x_a - x_b| \leq V' xaxbV V ′ V' V 为此时剩下的油量,走路会消耗你 ∣ x a − x b ∣ |x_a - x_b| xaxb升油。
  • 当你位于 N N N 个点的任意一个点时,可以将油量加至上限。
  • V ′ > 0 V' > 0 V>0 时,你可以 跳跃 到这 N N N 个点的任意一个,并将油量上限改为 ⌊ V ′ 2 ⌋ \left \lfloor \frac{V'}{2} \right \rfloor 2V

2 ≤ N , V ≤ 2 × 1 0 5 2 \leq N, V \leq 2 \times 10^5 2N,V2×105 − 1 0 9 ≤ x 1 < x 2 < ⋯ < x N ≤ 1 0 9 -10^9 \leq x_1 < x_2 < \dots < x_N \leq 10^9 109x1<x2<<xN109,保证 V V V x i x_i xi 都是整数。

分析:
首先不难发现,每次只会在油量满的情况下 跳跃,因此油量上限只会取到 T = { ⌊ V 2 i ⌋ } T = \{\left \lfloor \frac{V}{2^i} \right \rfloor\} T={2iV} 中的数。并且能观察出 ∣ T ∣ = log ⁡ 2 V |T| = \log_2 V T=log2V,将集合中的数从大到小排序,设第 i i i 个数为 T i T_i Ti
考虑 走路跳跃 交替使用的过程:假设当前上限为 v ∈ T v \in T vT,将相邻且距离不超过 v v v 的点连一条边,那么会形成若干条链。如果当前在 x x x 号点,一定是把 x x x 所在链上的点用 走路 遍历完后,跳跃到别的点上,然后令 v ← ⌊ v 2 ⌋ v \gets \left \lfloor \frac{v}{2} \right \rfloor v2v。并且不难发现,随着 v v v 的减小,一定是在原先的基础上删掉一些边得到新的图。
可以认为,遍历所有点的过程等价于 将所有点都分到一条链里,并且满足所有链是按照 S S S 中一个数为限制形成的,并且没有用到重复的数。进一步的,如果我们规定一个点为起点,那么就表明这个点一定在以 V V V 为限制形成的链里。
由此我们枚举起点 s s s,可以得到一个可行性 d p dp dp c h e c k check check
先将 s s s 所在的以 V V V 为限制形成的链上的所有点删去,然后对剩下的点 d p dp dp
d p i , S , j dp_{i, S, j} dpi,S,j 表示考虑了前 i i i 个点并且把它们都划分到了一条链中,已经用掉的数的集合为 S S S,第 i i i 个点所在链用的第 j j j 个数为限制是否可行。
i i i i + 1 i + 1 i+1 转移:首先看一下 x i + 1 ′ − x i x'_{i + 1} - x_{i} xi+1xi 是否小于等于 T j T_j Tj,如果小于等于可以转移给 d p i + 1 , S , j dp_{i + 1, S, j} dpi+1,S,j。否则可以枚举 S S S 中没用到的一个数将 i + 1 i +1 i+1 划分到一条新链中。
复杂度显然是不对的,考虑优化:首先能发现, j j j 时没有用的,因为我们每次新开一段一定直接延伸到最右边不能延伸的位置是最优的。接着你能发现,对于 S S S 相同的合法状态 d p i , S dp_{i, S} dpi,S,一定只有 i i i 最大的那个有用,因此直接改成最优化 d p dp dp
d p S dp_{S} dpS 表示用掉了 S S S 集合中的数,当前最靠右能划分到哪。转移枚举一个还没用的数 k k k ,假设当前位置在相邻距离不超过 T k T_k Tk 的情况下最远能走到 p p p,这个可以 O ( n log ⁡ V ) O(n \log V) O(nlogV) 预处理。那么可以用 p + 1 p + 1 p+1 更新 d p S ∪ k dp_{S \cup k} dpSk + 1 +1 +1 是因为新开段前可以跳跃,但是需要注意使用 S S S最后一个 还未被使用 的数时不能 + 1 +1 +1
这样单次 c h e c k check check 的复杂度就是 O ( V log ⁡ V ) O(V \log V) O(VlogV) 的。发现以 V V V 为限制形成的每条链中的点是等价的,并且如果此时链的数量大于 ∣ T ∣ |T| T 那么一定每个点都不能遍历其余点,而 ∣ T ∣ = log ⁡ V |T| = \log V T=logV,因此暴力枚举每一条链 c h e c k check check 即可。
总复杂度 O ( ( n + V ) log ⁡ 2 V ) O((n + V) \log^2 V) O((n+V)log2V)

CODE:

// 相当于把 n 个位置划分到 logV 段里,每段步长不同 
// 首先想出一个可行性dp,然后变成最优化问题即可。 
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, V, s[20], tot; // s[i] 表示 v / 2^i    取值为 [0, tot] 
int dp[1 << 19], x[N], y[N], len, lst[1 << 19], o[1 << 19]; // dp[S] 表示使用了 S 里的步长, 最靠后能延伸到哪 
int l[N], r[N], ct, R[N][19];
inline int jump(int s, int S, int l) { // 从 s 开始使用 l 步长最靠后能跳到哪 if(s > len) return s;else return R[s][l] - ((S ^ (1 << l)) == (1 << tot + 1) - 1);
}
inline void pre() { // 预处理 for(int i = 1; i <= tot; i ++ ) {for(int j = 1; j <= len; ) {int k = j + 1;while(k <= len && y[k] - y[k - 1] <= s[i]) k ++;for(int l = j; l < k; l ++ ) R[l][i] = k;j = k;}}
}
inline void DP(int l) {memset(dp, -1, sizeof dp);dp[1 << 0] = 1; // 能跳到 1 for(int s = 0; s < (1 << tot + 1); s ++ ) {if(dp[s] < 0) continue;else {for(int l = 0; l <= tot; l ++ ) {if(!(s >> l & 1)) { // 考虑使用 l 步长 dp[s ^ (1 << l)] = max(dp[s ^ (1 << l)], jump(dp[s], s, l));}}}}
}
int main() {scanf("%d%d", &n, &V);int nv = V;for(int i = 0; i <= 20; i ++ ) {s[i] = nv; if(nv == 0) {tot = i; break;}nv /= 2;}for(int i = 1; i <= n; i ++ ) scanf("%d", &x[i]);for(int i = 1; i <= n; ) {int j = i + 1;while(j <= n && x[j] - x[j - 1] <= V) j ++;l[++ ct] = i, r[ct] = j - 1;i = j;}if(ct > tot + 1) {for(int i = 1; i <= n; i ++ ) puts("Impossible"); return 0;}else {for(int i = 1; i <= ct; i ++ ) {len = 0;for(int j = 1; j <= ct; j ++ ) {if(j == i) continue;for(int k = l[j]; k <= r[j]; k ++ ) y[++ len] = x[k];}pre();DP(len);if(dp[(1 << tot + 1) - 1] >= len) {for(int k = l[i]; k <= r[i]; k ++ ) puts("Possible");}else {for(int k = l[i]; k <= r[i]; k ++ ) puts("Impossible");}}}return 0;
}

[ARC094D] Normalization(trick,转化)

题意:
给你一个仅包含 a , b , c a,b,c a,b,c 的字符串 S S S,你可以进行以下操作任意次:

  • 选择两个相邻的不相同字符,把它们替换成两个没有出现的那种字符。

例如你可以操作 a b → c c ab \to cc abcc
你需要求出一共能得到多少种 本质不同 的字符串。答案对 998244353 998244353 998244353 取模。

2 ≤ ∣ S ∣ ≤ 2 × 1 0 5 2 \leq |S| \leq 2 \times 10^5 2S2×105

分析:
很有 a t c atc atc 风格的一道题?反正我是没想到。
考虑将 a , b , c a,b,c a,b,c 分别别替换为 0 , 1 , 2 0,1,2 0,1,2。那么会发现 操作前后两个数的和在模 3 3 3 下相同
也就是说一个字符串 S S S 每个字符替换成数字后的和在任意操作后是不变的。定义 f ( S ) f(S) f(S) S S S 中的字符用数字替换后模 3 3 3 下的数字和。
那么很容易猜到 S S S 能变换得到的字符串与 f ( T ) = f ( S ) f(T) = f(S) f(T)=f(S) 的所有字符串 T T T 有很大关系。
经过打表,发现重要结论:

  • n > 3 n > 3 n>3 时, S S S 可以变换得到 所有 f ( T ) = f ( S ) f(T) = f(S) f(T)=f(S),且 T T T 中存在相邻相同字符的字符串 T T T

存在相邻相同字符也是好理解的,因为每次操作后必定存在相邻的相同字符。
那么就很容易做了,我们考虑拿 f ( T ) = f ( S ) f(T) = f(S) f(T)=f(S) T T T 的数量减去 f ( T ) = f ( S ) f(T) = f(S) f(T)=f(S) T T T 中不存在相邻相同字符的 T T T 的数量。
对于前者,显然答案是 3 n − 1 3^{n - 1} 3n1
对于后者,考虑一个 d p dp dp d p i , j , k dp_{i, j, k} dpi,j,k 表示考虑前 i i i 个字符,当前和模 3 3 3 j j j,第 i i i 个填了 k k k 的方案数,转移是平凡的。

需要特判 n ≤ 3 n \leq 3 n3 以及 S S S 中所有字符都相等的情况。
时间复杂度 O ( n ) O(n) O(n)

CODE:

// 无敌妙妙题 
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
const LL mod = 998244353;
int n;
char s[N];
LL f[N][3][3], mi[N]; // f[i][j][k] 表示考虑到前 i 个, 和为 j, 第i个填了 k 
int main() {scanf("%s", s + 1); n = strlen(s + 1); if(n <= 3) {if(n == 1) puts("1");else if(n == 2) {if(s[1] == s[2]) puts("1");else puts("2");}else {int cnt = (s[1] != s[2]) + (s[2] != s[3]);if(cnt == 0) puts("1");else if(cnt == 1) puts("6");else {if(s[1] != s[3]) puts("3");else puts("7");}}}else {mi[0] = 1; for(int i = 1; i <= n; i ++ ) mi[i] = mi[i - 1] * 3 % mod;bool flag = 0; int sum = 0;for(int i = 2; i <= n; i ++ ) flag |= (s[i] != s[i - 1]);for(int i = 1; i <= n; i ++ ) sum += (s[i] - 'a'); sum %= 3;if(!flag) puts("1");else { // 能得到所有和相同, 存在相邻相同字符的字符串 int c = 1;for(int i = 2; i <= n; i ++ ) if(s[i] == s[i - 1]) c = 0;for(int i = 0; i <= 2; i ++ ) f[1][i][i] = 1;for(int i = 2; i <= n; i ++ ) for(int j = 0; j <= 2; j ++ ) for(int k = 0; k <= 2; k ++ ) for(int l = 0; l <= 2; l ++ )if(k != l) f[i][(j + l) % 3][l] = (f[i][(j + l) % 3][l] + f[i - 1][j][k]) % mod; LL res = 0;for(int i = 0; i <= 2; i ++ ) res = (res + f[n][sum][i]) % mod;printf("%lld\n", (mi[n - 1] - res + mod + c) % mod); }}return 0;
}

[ARC125F] Tree Degree Subset Sum(结论,adhoc)

题意:
给你一棵 N N N 个点的树,你需要求出所有满足以下条件的二元组 ( x , y ) (x, y) (x,y) 的数量:

  • 0 ≤ x ≤ N 0 \leq x \leq N 0xN
  • 存在一种恰好选出 x x x 个点的方案,使得这 x x x 个点的度数和为 y y y

2 ≤ N ≤ 2 × 1 0 5 2 \leq N \leq 2 \times 10^5 2N2×105

分析:
首先树的形态没有任何作用,我们只需要求出度数数组就可以把树扔掉。
然后是非常超模的一步:
将所有 d e g i − 1 deg_i - 1 degi1,不难发现此时求得的所有二元组 ( x , y ′ ) (x, y') (x,y) 与原来的 ( x , y ) (x, y) (x,y) 一一对应。更具体的,现在的 ( x , y ) (x, y) (x,y) 对应了原来的 ( x , y + x ) (x, y + x) (x,y+x)
那么有重要结论:

  • 所有 d e g i − 1 deg_i - 1 degi1 后,此时求得的所有二元组 ( x , y ) (x, y) (x,y),满足将 y y y 固定后合法的 x x x 是一段区间。

这个也可能是打表所有 ( x , y − x ) (x, y - x) (x,yx) 时看出的结论。

证明:
假设 d e g i − 1 deg_i - 1 degi1 后有 k k k 0 0 0。对于一个 y y y,合法的最小 x x x m n mn mn,最大 x x x m x mx mx。那么 m n mn mn 个里面一定不包含 0 0 0 m x mx mx 里面一定包含了所有的 k k k 0 0 0。因此可以将 m n mn mn 向上调整至 m n + k mn + k mn+k m x mx mx 向下调整至 m x − k mx - k mxk,只需要证明 m n + k ≥ m x − k mn + k \geq mx - k mn+kmxk,即 2 k ≥ m x − m n 2k \geq mx - mn 2kmxmn

由于 ∑ d e g i − 1 = n − 2 \sum deg_i - 1 = n - 2 degi1=n2,所以对于合法对 ( x , y ) (x, y) (x,y),有:

  • x − k ≤ y ≤ n − 2 ⇒ x ≤ y + k x - k \leq y \leq n - 2\Rightarrow x \leq y + k xkyn2xy+k

那么一定存在 ( n − x , n − 2 − y ) (n - x, n - 2 - y) (nx,n2y),因此有:

  • n − x − k ≤ n − 2 − y ≤ n − 2 ⇒ x ≥ y + 2 − k n - x - k \leq n - 2 - y \leq n - 2\Rightarrow x \geq y + 2 - k nxkn2yn2xy+2k

因此解出来 x x x 的一个范围:
y − k + 2 ≤ x ≤ y + k y - k + 2 \leq x \leq y + k yk+2xy+k

那么 m x − m n ≤ 2 k − 2 ≤ 2 k mx - mn \leq 2k - 2 \leq 2k mxmn2k22k,证毕。

因此将 度数 看作 体积点的数量 看作 价值,跑 最优化背包 即可。
但是这样暴力是 O ( n 2 ) O(n^2) O(n2) 的。注意到不同的 d e g i deg_i degi 只有 O ( n ) O(\sqrt{n}) O(n ) 种,这是因为 d e g i deg_i degi 的和为 2 n − 2 2n - 2 2n2
因此可以跑 单调队列优化多重背包。复杂度 O ( n n ) O(n \sqrt{n}) O(nn )

CODE:

// 将每个点度数减 1 后, 对于一个固定的 y, 合法的 x 是一段区间 
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int n, deg[N], c[N];
int f[N], g[N], tf[N], tg[N]; // f[i] 表示现在度数和为 i 选中的最少点, g[i] 表示最多点 
int main() {scanf("%d", &n);for(int i = 1; i < n; i ++ ) {int u, v; scanf("%d%d", &u, &v);deg[u] ++; deg[v] ++;}for(int i = 1; i <= n; i ++ ) c[-- deg[i]] ++; // 每个点度数减 1 memset(f, 0x3f, sizeof f);memset(g, 0xcf, sizeof g);g[0] = f[0] = 0; for(int i = 0; i < n; i ++ ) {if(!c[i]) continue;if(i == 0) {for(int j = 0; j <= n; j ++ ) g[j] += c[i];}else {for(int r = 0; r < i; r ++ ) { // 枚举余数 deque< int > q1, q2; // 最小和最大 for(int j = 0; j <= (n - r) / i; j ++ ) { // 数量 while(!q1.empty() && f[q1.back() * i + r] - q1.back() >= f[j * i + r] - j) q1.pop_back();while(!q1.empty() && j - q1.front() > c[i]) q1.pop_front();q1.push_back(j);tf[j * i + r] = f[q1.front() * i + r] + (j - q1.front());while(!q2.empty() && g[q2.back() * i + r] - q2.back() <= g[j * i + r] - j) q2.pop_back();while(!q2.empty() && j - q2.front() > c[i]) q2.pop_front();q2.push_back(j);tg[j * i + r] = g[q2.front() * i + r] + (j - q2.front());}}for(int j = 0; j <= n; j ++ ) f[j] = tf[j], g[j] = tg[j];}}LL res = 0;for(int i = 0; i <= n; i ++ ) {if(g[i] >= f[i]) res += g[i] - f[i] + 1;}cout << res << endl;return 0;
}

[AGC049E] Increment Decrement(slope trick, 计数技巧,神仙题)

题意:
我们可以对一个非负整数序列 { A i } \{A_i\} {Ai} 进行以下两种操作任意多次:

  • 选定一项使其 + 1 +1 +1 − 1 -1 1,花费为 1 1 1
  • 选定一个区间使其中的每一项 + 1 +1 +1 − 1 -1 1,花费为 C C C

定义一个非负整数序列 { A i } \{A_i\} {Ai} 的花费为将一个初始全为 0 0 0 的序列变成序列 A A A 的最小花费。

给定 N N N 个长为 K K K 的序列 B i B_i Bi,可以将 A i A_i Ai 赋值为 B i , 1 … K B_{i, 1 \dots K} Bi,1K 中任意一项。你需要求出 K N K^N KN 种可能的 A A A 序列的花费之和。

1 ≤ N ≤ 50 , 1 ≤ C ≤ 50 , 1 ≤ K ≤ 50 1 \leq N \leq 50, 1 \leq C \leq 50, 1\leq K \leq 50 1N50,1C50,1K50 1 ≤ B i , j ≤ 1 0 9 1 \leq B_{i, j} \leq 10^9 1Bi,j109

分析:
神题!!!

这种题的一般思路是想怎样对于固定的 A A A 序列求最优答案,然后转计数就可以 d p dp dp d p dp dp 或者一些别的思路。

那么首先考虑怎么对一个固定的 A A A 求答案:

显然一操作和二操作顺序任意,先执行完所有二操作,假设得到了序列 P P P,那么一操作的花费就是 ∑ i = 1 n ∣ P i − A i ∣ \sum_{i = 1}^{n}|P_i - A_i| i=1nPiAi。二操作的花费即为 ∑ i = 1 n C × max ⁡ ( P i − P i − 1 , 0 ) \sum_{i = 1}^{n} C \times \max(P_i - P_{i - 1}, 0) i=1nC×max(PiPi1,0)。可以认为 P 0 = 0 P_0 = 0 P0=0

可以得到一个 d p dp dp
f i , j f_{i, j} fi,j 表示填过了前 i i i 个位置的 P P P,第 i i i 个位置填了 j j j 的最小花费。那么有转移:

f i , j = min ⁡ k ( f i − 1 , k + C × max ⁡ ( j − k , 0 ) ) + ∣ j − A i ∣ f_{i, j} = \min\limits_{k}(f_{i - 1, k} + C \times \max(j - k, 0)) + |j - A_{i}| fi,j=kmin(fi1,k+C×max(jk,0))+jAi

看到了加绝对值函数,猜测 f i f_i fi 关于 j j j 下凸。下面来 归纳证明 一下:
套路的,将转移拆成两步:

f i , j ← min ⁡ k ( f i − 1 , k + C × max ⁡ ( j − k , 0 ) ) f_{i, j} \gets \min\limits_{k}(f_{i - 1, k} + C \times \max(j - k, 0)) fi,jkmin(fi1,k+C×max(jk,0))

f i f_i fi 加绝对值函数 ∣ j − A i ∣ |j - A_i| jAi

第二步显然不影响下凸性,只需要证明第一步转移后下凸即可。

f i − 1 f_{i - 1} fi1 关于 j j j 下凸,最小值取到 f i − 1 , k f_{i - 1, k} fi1,k,设 w w w 为满足 f i − 1 , w + 1 − f i − 1 , w > C f_{i - 1, w + 1} - f_{i - 1, w} > C fi1,w+1fi1,w>C 的最小的数。
那么当 j ≤ k j \leq k jk,显然 f i , j ← f i − 1 , k f_{i, j} \gets f_{i - 1, k} fi,jfi1,k
j ≥ w j \geq w jw 时,显然 f i , j ← f i − 1 , w + C × ( j − w ) f_{i, j} \gets f_{i - 1, w} + C \times (j - w) fi,jfi1,w+C×(jw)
其余的 j j j 都有 f i , j ← f i − 1 , j f_{i, j} \gets f_{i - 1, j} fi,jfi1,j
概括的说就是将最小值左边部分推平,斜率大于 C C C 的部分改成一条斜率为 C C C 的直线。
那么图形的斜率仍然单调递增,还是下凸。
加上第二步转移来看,会发现实际上函数的斜率只存在 [ − 1 , C + 1 ] [-1, C + 1] [1,C+1]。第一步转移就是将斜率为 − 1 -1 1 的部分推平并将斜率为 C + 1 C + 1 C+1 的部分删去。

那么可以 s l o p e t i r c k slope \ tirck slope tirck 维护。为了方便,我们令 f 0 , j = C × j f_{0, j} = C \times j f0,j=C×j,这样正常转移也是对的。也就是首先往函数斜率变化点的可重集里插入 C C C 0 0 0。考虑两步操作变成了什么:

  • i > 1 i > 1 i>1 时,将可重集里的最小值和最大值删去。
  • 插入两个 A i A_i Ai 表示在 A i A_i Ai 部分斜率变化了 2 2 2
  • 记此时可重集的最小值为 p p p,将答案加上 A i − p A_i - p Aip,表示最小值的增量。

那么我们可以在 O ( n log ⁡ V ) O(n \log V) O(nlogV) 的复杂度解决这个问题。

考虑第二部分,改成计数:
我们要对所有可能的 A A A 求一次答案加起来。观察求解答案的过程,可以分作两部分:

  • + A i +A_i +Ai
  • 减去当前可重集的最小值

第一部分的贡献是简单的,只需要将 ∑ i = 1 n K n − 1 ∑ j = 1 K B i , j \sum_{i = 1}^{n} K^{n - 1} \sum_{j = 1}^{K}B_{i, j} i=1nKn1j=1KBi,j 加到答案中即可。
对于第二部分:
考虑枚举一种数 x x x 计算它作为最小值被减了多少次。
维护可重集是困难的,但是如果数字只有 0 / 1 0/1 0/1 是好做的。
因此我们将 x x x 被减的次数拆成 ≤ x \leq x x的数被减的次数减去 < x < x <x 的数被减的次数。
对于前者,可以将所有 ≤ x \leq x x 的数看作 0 0 0,其余看作 1 1 1。对于后者只需要将 < x < x <x 的数看作 0 0 0,其余看作 1 1 1 即可。
那么现在问题就变成了数字只有 0 , 1 0,1 0,1 两种,你需要求出 K n K^n Kn 中情况中 0 0 0 作为最小值被减了几次。
这个显然是简单的,每步操作后都有 C + 2 C+2 C+2 个数,只需要记录其中有多少个 0 0 0 就能转移。
更简单的,注意到只有可重集中所有 C + 2 C + 2 C+2 个数都是 1 1 1 0 0 0 才不是最小值。
那么考虑一个容斥,总的拿出最小值次数减去最小值取 1 1 1 的次数。
总的次数显然是 n × K n n \times K^n n×Kn
对第二部分,设一个 d p dp dp f i , j f_{i, j} fi,j 表示考虑了前 i i i A i A_i Ai 的取值,当前可重集中有 j j j 1 1 1 的方案数。转移只需要考虑当前位置选 0 0 0 还是 1 1 1 并乘上系数即可。那么第二部分的答案就是 ∑ i = 1 n f i , C + 2 × K n − i \sum_{i = 1}^{n}f_{i, C + 2} \times K^{n - i} i=1nfi,C+2×Kni

最小值种类数 n k nk nk,每次 d p dp dp 复杂度 O ( n k ) O(nk) O(nk) ,总复杂度 O ( n 2 k 2 ) O(n^2k^2) O(n2k2)

CODE:

// 绝世好题, 考察 slope trick 和 计数技巧 
#include<bits/stdc++.h>
using namespace std;
const int N = 55;
typedef long long LL;
const int mod = 1e9 + 7;
int mi[N], res;
int n, C, K, a[N][N], c[N], b[N * N], tot;
int dp[N][N]; // dp[i][j] 表示考虑到 i, 当前有 j 个 1 的方案数 
inline int del(int x, int y) {return x - y < 0 ? x - y + mod : x - y;} 
inline int add(int x, int y) {return x + y >= mod ? x + y - mod : x + y;}
inline int mul(int x, int y) {return 1LL * x * y % mod;}
inline int f(int x) { // 将 <= x 的看作 0, > x 的看作 1, 求 K^n 种有多少次最小值为 0 int ret = mul(n, mi[n]);for(int i = 1; i <= n; i ++ ) {c[i] = 0;for(int j = 1; j <= K; j ++ ) c[i] += (a[i][j] > x);}memset(dp, 0, sizeof dp);dp[0][0] = 1;for(int i = 1; i <= n; i ++ ) {if(i == 1) {dp[i][0] = mul(dp[i - 1][0], K - c[i]);dp[i][2] = mul(dp[i - 1][0], c[i]);}else {for(int j = 0; j <= C + 2; j ++ ) { // 枚举上一个有多少个 1 int &v = dp[i][j - (j == C + 2) - (j > 0)];v = add(v, mul(dp[i - 1][j], K - c[i])); // 放 0int &z = dp[i][j - (j == C + 2) - (j > 0) + 2];z = add(z, mul(dp[i - 1][j], c[i]));}}ret = del(ret, mul(dp[i][C + 2], mi[n - i]));}return ret;
}
int main() {scanf("%d%d%d", &n, &C, &K);for(int i = 1; i <= n; i ++ ) for(int j = 1; j <= K; j ++ ) {scanf("%d", &a[i][j]);b[++ tot] = a[i][j];}mi[0] = 1; for(int i = 1; i <= n; i ++ ) mi[i] = mul(mi[i - 1], K);for(int i = 1; i <= n; i ++ ) // 所有 a[i][j] 的贡献 for(int j = 1; j <= K; j ++ ) res = add(res, mul(mi[n - 1], a[i][j]));sort(b + 1, b + tot + 1);tot = unique(b + 1, b + tot + 1) - (b + 1);for(int i = 1; i <= tot; i ++ ) { // 枚举最小值, 计算它们的系数 res = del(res, mul(del(f(b[i]), f(b[i] - 1)), b[i]));}cout << res << endl;return 0;
}

相关文章:

4.16 AT好题选做

文章目录 前言[ARC103D] Distance Sums(确定树的形态,trick)[AGC062B] Split and Insert(区间 d p dp dp)[AGC012E] Camel and Oases(状压&#xff0c;可行性dp转最优性dp)[ARC094D] Normalization(trick&#xff0c;转化)[ARC125F] Tree Degree Subset Sum(结论&#xff0c;a…...

数据库-day06

一、实验名称和性质 分类查询 验证 综合 设计 二、实验目的 1&#xff0e;掌握数据查询的Group by &#xff1b; 2&#xff0e; 掌握聚集函数的使用方法。 三、实验的软硬件环境要求 硬件环境要求&#xff1a; PC机(单机) 使用的软件名称、版本号以及模块&#xff1a; …...

基于Flask的漏洞挖掘知识库系统设计与实现

基于Flask的漏洞挖掘知识库系统设计与实现 一、系统架构设计 1.1 整体架构 本系统采用经典的三层Web架构&#xff0c;通过Mermaid图展示的组件交互流程清晰呈现了以下核心模块&#xff1a; 前端展示层&#xff1a;基于Bootstrap5构建响应式界面业务逻辑层&#xff1a;Flask…...

小白从0学习网站搭建的关键事项和避坑指南

以下是针对小白从零学习网站搭建时需要注意的关键事项和避坑指南&#xff0c;帮助你高效学习、少走弯路&#xff1a; 一、学习路径注意事项 不要跳过基础 误区&#xff1a;直接学习框架&#xff08;如 React、Laravel&#xff09;而忽视 HTML/CSS/JS 基础。 正确做法&#xff…...

OpenAI 推出一对 AI 推理模型 o3 和 o4-mini

OpenAI 于 2025 年 4 月 16 日&#xff08;美国东部时间&#xff09;宣布推出两款全新的 AI 推理模型——o3 与 o4-mini&#xff0c;它们能够在给出最终回答前进行思考与推理。 本文中所有的 ChatGPT 服务&#xff0c;由 ChatShare 镜像站 提供&#xff0c;无需担心网络和地区限…...

知识了解03——怎么解决使用npm包下载慢的问题?

1、为什么使用npm下载包会下载的慢 因为使用npm下载包时&#xff0c;默认使用国外服务器进行下载&#xff0c;此时的网络传输需要经过漫长的海底电缆&#xff0c;因此下载速度会变慢 2、怎么解决&#xff1f;&#xff08;切换镜像源&#xff09; &#xff08;1&#xff09;方…...

【网络】IP层的重要知识

目录 1.IP层的作用 2.主机和节点 3.网络层和数据链路层的关系 4.路由控制 4.1.路由控制的过程 4.2. IP地址与路由控制 4.3.路由控制表的聚合 4.4.静态路由和动态路由 4.5.动态路由的基础 5.数据链路的抽象化 5.1.数据链路不同&#xff0c;MTU则相异 5.2.路径MTU发…...

【随身WIFI】随身WiFi Debian系统优化教程

0.操作前必看 本教程基于Debian系统进行优化&#xff0c;有些操作对随身WiFi来说可能会带来负优化&#xff0c;根据需要选择。 所有操作需要在root用户环境下运行&#xff0c;否则都要加sudo 随身wifi Debian系统&#xff0c;可以去某安的随声WiFi模块自行搜索刷机 点赞&am…...

IPCC指南主要变化(各版本)

1996年IPCC国家温室气体清单指南 背景&#xff1a;是IPCC较早发布的指南之一&#xff0c;为国家温室气体清单编制提供了基础方法。 内容&#xff1a;包括了对温室气体排放源和汇的估算方法&#xff0c;涵盖了能源、工业、农业等多个部门。 2006年IPCC国家温室气体清单指南 背…...

关于Diamond机械手的运动学与动力学的推导

1.关于Diamond机械手 &#xff08;1&#xff09;位置模型推导 逆解&#xff1a;机械末端平台的位置与驱动关节之间的关系。 设p点在xy平面的坐标是&#xff08;x&#xff0c;y&#xff09;T&#xff0c;此时根据向量求解 OP等于向量r等于e向xy轴的向量主动臂长度向xy轴的向量…...

@JsonSerialize注解自定义序列化方式

JsonSerialize注解自定义序列化方式 文章目录 JsonSerialize注解自定义序列化方式**前言****创建自定义序列化器****应用自定义序列化器****测试序列化结果****高级用法&#xff1a;全局注册序列化器****关键点解析****常见问题解决****问题1&#xff1a;序列化结果不符合预期*…...

第二篇:linux之Xshell使用及相关linux操作

第二篇&#xff1a;linux之Xshell使用及相关linux操作 文章目录 第二篇&#xff1a;linux之Xshell使用及相关linux操作一、Xshell使用1、Xshell安装2、Xshell使用 二、Bash Shell介绍与使用1、什么是Bash Shell(壳)&#xff1f;2、Bash Shell能干什么&#xff1f;3、平时如何使…...

qt中关于思源雅黑字体的使用

首先&#xff0c;需要下载一份思源雅黑字体&#xff0c;我放在了下面位置&#xff0c;https://download.csdn.net/download/Littlehero_121/90631851 2、关于qt中的使用操作&#xff0c;如下&#xff1a; //QString path "绝对路径";QString path QCoreApplicatio…...

用 MongoIndexStore 实现对话存档和恢复 实现“多用户、多对话线程”场景(像一个 ChatGPT 对话列表那样)

用LlamaIndex写两个完整实用的案例&#xff01; 实现如何用 MongoIndexStore 实现对话存档和恢复实现“多用户、多对话线程”场景&#xff08;像一个 ChatGPT 对话列表那样&#xff09; ✅ 案例一&#xff1a;使用 MongoIndexStore 实现对话存档 恢复 单用户 单对话线程&am…...

接口测试:实用指南4.0

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…...

2000-2017年各省国有经济煤气生产和供应业固定资产投资数据

2000-2017年各省国有经济煤气生产和供应业固定资产投资数据 1、时间&#xff1a;2000-2017年 2、来源&#xff1a;国家统计局、能源年鉴 3、指标&#xff1a;行政区划代码、城市、年份、国有经济煤气生产和供应业固定资产投资 4、范围&#xff1a;31省 5、指标说明&#x…...

AOP的基本应用案例---统计每个函数的执行时间

1.导入依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency> 2.准备好要计算的SpringBoot的项目(本案例以service的实现类为例) 3.编写AOP的代码: package c…...

前端复习遗忘的知识点

这个是我个人平常学习一些博主的东西&#xff0c;如果侵权请联系我或者让我标上博主平台等信息&#xff0c;谢谢&#xff01; 1&#xff1a;如图涉及知识点jq&#xff1a; 1.获取元素 document.getElementById(""); document.getElementsByClassName(); document.g…...

Unity3d 6(6000.*.*)版本国区下载安装参考

前言 Unity3d 6.是最新的版本&#xff0c;是与来自世界各地的开发者合作构建、测试和优化的成果&#xff0c;现在可以完全投入生产&#xff0c;是我们迄今为止性能最出色、最稳定的 Unity 版本。Unity 6 有许多令人兴奋的新工具和功能&#xff1a;端到端多人游戏工作流程将加速…...

【JavaEE】Maven配置

一、Maven简介 什么是Maven&#xff1f; Maven是一个基于项目对象模型&#xff08;POM&#xff09;构建的自动化工具&#xff0c;主要用于Java项目构建、依赖管理和项目信息管理 我理解的Maven&#xff1a;自动下载和管理“代码零件”&#xff08;比如别人写好的工具包&#x…...

Java排序算法百科全书:原理、实现与实战指南

一、排序算法全景视图 1. 算法分类体系 graph TDA[排序算法] --> B[比较排序]A --> C[非比较排序]B --> B1[基本排序]B1 --> B11[冒泡排序]B1 --> B12[选择排序]B1 --> B13[插入排序]B --> B2[高效排序]B2 --> B21[快速排序]B2 --> B22[归并排序]…...

大模型在教育领域的五大应用

大模型在教育领域的五大应用 随着人工智能技术的迅猛发展&#xff0c;特别是大模型&#xff08;如GPT-3、BERT等&#xff09;的出现&#xff0c;教育领域正迎来一场前所未有的变革。大模型不仅能够处理复杂的自然语言任务&#xff0c;还能够通过深度学习算法理解和生成高质量的…...

Lesson 12 Goodbye and good luck

Lesson 12 Goodbye and good luck 词汇 luck n. 运气&#xff0c;幸运 相关&#xff1a;lucky a. 幸运的    luckily ad. 幸运地    unlucky a. 不幸的 搭配&#xff1a;lucky number 幸运数字    lucky color 幸运色    lucky day 幸运日    lucky dog 幸运儿…...

数据结构-前缀树

一、引言 前缀树又叫字典树&#xff0c;可以快速查找字符串或字符串前缀出现的次数&#xff0c;方便进行前缀匹配、词频统计 二、字典树模型 现有一个字典树&#xff0c;里面有money、mother、salary、salary、say五个单词 其中根节点位置还没有字符&#xff0c;相当于空串&am…...

搭建 vue 项目环境详细步骤

在平常的开发工作中&#xff0c;我们经常需要对项目进行打包&#xff0c;后端项目打包及部署在前面总结过。那么&#xff0c;现在前端基本都是 vue 项目&#xff0c;那么应该如何搭建一个 vue 环境呢&#xff1f;下载一个前端项目应该如何启动呢&#xff1f;今天&#xff0c;我…...

【2025最新版】火鸟门户v8.5系统源码+PC、H5、小程序 +数据化大屏插件

一.介绍 火鸟地方门户系统V8.5源码 系统包含4端&#xff1a; PCH5小程序APP 二.搭建环境 系统环境&#xff1a;CentOS、 运行环境&#xff1a;宝塔 Linux 网站环境&#xff1a;Nginx 1.2.22 MySQL 5.6 PHP-7.4 常见插件&#xff1a;fileinfo &#xff1b; redis 三.测…...

【eNSP实验】OSPF单区域配置

简介 OSPF&#xff08;开放最短路径优先&#xff09;是一种基于链路状态算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于自治系统内部动态路由。其核心机制为&#xff1a;各路由器通过泛洪链路状态通告&#xff08;LSA&#xff09;同步网络拓扑&#xff0c;构…...

e实例性能测评:Intel Xeon Platinum处理器,经济型入门级服务器

阿里云服务器ECS经济型e系列是阿里云面向个人开发者、学生、小微企业&#xff0c;在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器&#xff0c;阿里云百科分享CPU处理器采用Intel Xeon Platinum架构处理器&#xff0c;支持1:1、1:2、1:4多种处理器内存配…...

uniapp APP端 DOM生成图片保存到相册

<template> <view class"container" style"padding-bottom: 30rpx;"> <view class"hdbg pr w100 " style"height: 150rpx;"> <top-bar content分享 Back"Back"></top-b…...

Leetcode刷题 由浅入深之哈希表——242. 有效的字母异位词

目录 &#xff08;一&#xff09;字母异位词的C实现 写法一&#xff08;辅助数组&#xff09; &#xff08;二&#xff09;复杂度分析 时间复杂度 空间复杂度 &#xff08;三&#xff09;总结 【题目链接】242.有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; …...

Opencv函数及练习题

一、函数整理&#xff1a; 1、cv2.adaptiveThreshold&#xff08;&#xff09; 2、 cv2.split&#xff08;&#xff09; 3、cv2.merge&#xff08;&#xff09; 4、cv2.add&#xff08;&#xff09; 5、cv2.bitwise_and&#xff08;&#xff09; 6、 cv2.inRange&#xff08;&…...

16-算法打卡-哈希表-两个数组的交集-leetcode(349)-第十六天

1 题目地址 349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09;349. 两个数组的交集 - 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1&#xff1a;输入&#xff1a;nu…...

计算机视觉——JPEG AI 标准发布了图像压缩新突破与数字图像取证的挑战及应对策略

概述 今年2月&#xff0c;经过多年旨在利用机器学习技术开发一种更小、更易于传输和存储且不损失感知质量的图像编解码器的研究后&#xff0c;JPEG AI国际标准正式发布。 来自JPEG AI官方发布流&#xff0c;峰值信噪比&#xff08;PSNR&#xff09;与JPEG AI的机器学习增强方法…...

【JavaWeb后端开发01】Maven入门

课程内容&#xff1a; 初始Maven Maven概述 Maven模型 Maven仓库介绍 Maven安装与配置 IDEA集成Maven 依赖管理 单元测试 文章目录 1. 初始Maven1.1 介绍1.2 Maven的作用1.2.1 依赖管理1.2.2 项目构建1.2.3 统一项目结构 2. Maven概述2.1 Maven介绍2.2 Maven模型2.3 Ma…...

【Leetcode】16. 最接近的三数之和

一、题目描述 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1: 输入:nums = [-1,2,1,-4], target = 1 输出:2解释: 与 target 最接近…...

目标检测概述

为什么基于卷积网络的目标检测模型在预测后要使用非极大值抑制 基于卷积网络的目标检测模型可能会在目标的相邻区域生成多个相互重叠框&#xff0c;每个框的预测结果都是同一个目标&#xff0c;引起同一目标的重复检测。造成这一现象的原因主要有两个&#xff0c; 基于卷积网络…...

摄影跟拍预定|基于java+vue的摄影跟拍预定管理系统(源码+数据库+文档)

摄影跟拍预定管理系统 目录 基于SprinBootvue的摄影跟拍预定管理系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3摄影师功能模块 4用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获…...

--图--

并查集 并查集原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述…...

Python中的count()方法

文章目录 Python中的count()方法基本语法在不同数据类型中的使用1. 列表(List)中的count()2. 元组(Tuple)中的count()3. 字符串(String)中的count() 高级用法1. 指定搜索范围2. 统计复杂元素 注意事项 Python中的count()方法 前言&#xff1a;count()是Python中用于序列类型&a…...

通过gird布局实现div的响应式分布排列

目标&#xff1a;实现对于固定宽度的div盒子在页面中自适应排布&#xff0c;并且最后一行的div盒子可以与前面的盒子对齐。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" con…...

Edge 浏览器推出 Copilot Vision:免费实时解析屏幕内容;Aqua Voice:极速 AI 语音输入工具丨日报

开发者朋友们大家好 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看…...

Linux 防火墙( iptables )

目录 一、 Linux 防火墙基础 1. 防火墙基础概念 &#xff08;1&#xff09;防火墙的概述与作用 &#xff08;2&#xff09;防火墙的结构与匹配流程 &#xff08;3&#xff09;防火墙的类别与各个防火墙的区别 2. iptables 的表、链结构 &#xff08;1&#xff09;规则表 …...

Hook插件

hook插件 1.概念 在JavaScript中&#xff0c;hook是一种能够拦截和修改函数或方法行为的技术。通过使用hook&#xff0c;开发者可以在现有的函数执行前、执行后或者替换函数的实现逻辑。hook目的是找到函数入口以及一些参数变化&#xff0c;便于分析js逻辑。 2.hook的作用&a…...

ORA-00600: internal error code, arguments: [kcratr_nab_less_than_odr], [1],

因客户机房断电&#xff0c;2台主机和共享存储全部断电&#xff0c;来电后&#xff0c;集群启动正常&#xff0c;实例无法正常启动&#xff0c;手动启动报错如下 SQL > startup; ORACLE instance started. Total System Global Area 3.9551E10 bytes Fixed Size …...

R4打卡——tensorflow实现火灾预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 1.检查GPU import tensorflow as tf import pandas as pd import numpy as npgpus tf.config.list_physical_devices("GPU") if gpus:…...

基于AI大语言模型的历史文献分析在气候与灾害重建领域中的技术应用

随着人工智能技术的快速发展&#xff0c;大语言模型&#xff08;如GPT、BERT等&#xff09;在自然语言处理领域取得了显著进展&#xff0c;特别是在非结构化文本数据的分析方面&#xff0c;极大地拓展了我们的研究视角。这些技术不仅提高了处理和理解文本数据的效率&#xff0c…...

CSS 字体背景波浪

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>字体背景波浪</title><style>/* HTML: <div class"loader"></div> *//* HTML: <div class"loader"…...

2025能源网络安全大赛CTF --- Crypto wp

文章目录 前言simpleSigninNumberTheory 前言 大半年以来写的第一篇文章&#xff01;&#xff01;&#xff01; simpleSignin 题目&#xff1a; from Crypto.Util.number import * from gmpy2 import * import osflag bxxx p next_prime(bytes_to_long(os.urandom(128))…...

Redis面试——日志

一、RDB&#xff08;Redis DataBase&#xff09; RDB 全程是 Redis DataBase&#xff0c;它是一种将 Redis 在某一时刻内存中的数据以快照形式保存到磁盘的机制 &#xff0c;相当于给执行save/bgsave命令时刻的内存数据库数据拍了一张快照我们如果通过save命令来执行快照&…...

计算机视觉与深度学习 | 基于YOLOv8与光流法的目标检测与跟踪(Python代码)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 目标检测与跟踪 关键实现逻辑检测-跟踪协作机制‌特征点选择策略‌运动…...