2023 年牛客多校第七场题解

A Random Addition

题意:给定长度为 n n n 的数列,初始全为 0 0 0。对其中 m m m 个区间 [ l i , r i ] [l_i,r_i] [li,ri] 执行加 x x x 操作, x x x 等概率从 [ 0 , 1 ] [0,1] [0,1] 实数集合选取。这些区间包含或不相交。 q q q 次询问整个序列最大值在 [ p , q ] [p,q] [p,q] 的概率对 998 244 353 998\ 244\ 353 998 244 353 取模。 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105 1 ≤ m ≤ 200 1 \le m \le 200 1m200 0 ≤ p ≤ q ≤ 10 0 \le p \le q \le 10 0pq10

解法:首先考虑一个数字仅被加一次,则该数字取值的概率密度函数为:
P ( x ) = f 1 ( x ) = { 1 , 0 ≤ x ≤ 1 0 , o t h e r w i s e P(x)=f_1(x)= \begin{cases} 1,0 \le x \le 1\\ 0,{\rm otherwise} \end{cases} P(x)=f1(x)={1,0x10,otherwise
如果加两次,则该数字的取值概率密度函数就需要使用到卷积:
f 2 ( x ) = P ( x ) ∗ P ( x ) = ∫ − ∞ + ∞ P ( t ) P ( x − t ) d t = { x , 0 ≤ x ≤ 1 2 − x , 1 < x ≤ 2 0 , o t h e r w i s e \begin{aligned} f_2(x)&=P(x)*P(x)\\ &=\int_{-\infty}^{+\infty}P(t)P(x-t){\rm d}t\\ &=\begin{cases} x,0 \le x \le 1\\ 2-x,1 <x \le 2\\ 0,{\rm otherwise} \end{cases} \end{aligned} f2(x)=P(x)P(x)=+P(t)P(xt)dt= x,0x12x,1<x20,otherwise
即,两个窗函数的卷积是一个三角波函数。

如果该数字加 k k k 次,则可以考虑将 P ( x ) P(x) P(x) 进行 k k k 次卷积。使用数学归纳法证明该 f k ( x ) f_k(x) fk(x) 一定是一个 k k k 段函数,每段函数都可以使用一个多项式表达。假设经过第 k − 1 k-1 k1 次卷积后整个函数分为 k − 1 k-1 k1 段,其中第 j j j j ∈ [ 1 , k − 1 ] j \in [1,k-1] j[1,k1])个分段函数对应区间为 [ j − 1 , j ] [j-1,j] [j1,j]。考虑对这个函数再做一次卷积:
f k , j ( x ) = ∫ − ∞ + ∞ f k − 1 , j ( t ) P ( x − t ) d t = ∫ x − 1 x f k − 1 , j ( t ) d t = { ∫ j − 1 x f k − 1 , j ( t ) d t , x ∈ [ j − 1 , j ] ∫ x − 1 j f k − 1 , j ( t ) d t , x ∈ [ j , j + 1 ] \begin{aligned} f_{k,j}(x)&=\int_{-\infty}^{+\infty}f_{k-1,j}(t)P(x-t){\rm d}t\\ &=\int_{x-1}^{x}f_{k-1,j}(t){\rm d}t\\ &= \begin{cases} \displaystyle \int_{j-1}^{x}f_{k-1,j}(t){\rm d}t, x\in[j-1,j]\\ \displaystyle \int_{x-1}^{j}f_{k-1,j}(t){\rm d}t, x\in[j,j+1]\\ \end{cases} \end{aligned} fk,j(x)=+fk1,j(t)P(xt)dt=x1xfk1,j(t)dt= j1xfk1,j(t)dt,x[j1,j]x1jfk1,j(t)dt,x[j,j+1]
若记 F ( x ) = ∫ 0 x f ( t ) d t \displaystyle F(x)=\int_{0}^x f(t){\rm d}t F(x)=0xf(t)dt,则卷积式可写为:
f k , j ( x ) = { F ( x ) − F ( j − 1 ) , x ∈ [ j − 1 , j ] F ( j ) − F ( x − 1 ) , x ∈ [ j , j + 1 ] f_{k,j}(x)= \begin{cases} \displaystyle F(x)-F(j-1), x\in[j-1,j]\\ \displaystyle F(j)-F(x-1), x\in[j,j+1]\\ \end{cases} fk,j(x)={F(x)F(j1),x[j1,j]F(j)F(x1),x[j,j+1]
回到本题,由于需要求的是小于等于某个特定数字的概率,因而需要对概率密度函数进行积分得到概率分布函数,不妨直接维护概率分布函数。

由于题目中有个强约束——区间包含或者不相交,因而这些区间组成一个树形结构,可以考虑 dfs 遍历得到每个区间上的概率分布函数。当子树中存在多个不相交的直接子区间时,父节点需要将这些区间的概率密度函数一一通过多项式卷积乘到对应分段区间上,然后父区间再自行进行卷积运算。这么做的原因是因为对于两个独立变量的最大值的概率分布函数 Pr ⁡ ( max ⁡ ( X 1 , X 2 ) ≤ x ) = Pr ⁡ ( X 1 ≤ x ) Pr ⁡ ( X 2 ≤ x ) \Pr(\max(X_1,X_2) \le x)= \Pr(X_1 \le x)\Pr(X_2 \le x) Pr(max(X1,X2)x)=Pr(X1x)Pr(X2x)

最后查询仅需要查询根节点的区间(即整个数组)上的概率分布函数即可。如果使用朴素多项式乘法(卷积),总复杂度 O ( 10 m 3 ) \mathcal O(10m^3) O(10m3)

关于多项式函数的卷积和乘积,可以参看附录乙·乘积、卷积部分。

感谢致远星的代码:

#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int n, m, t;
struct qq
{int l, r;bool operator<(const qq &b)const{if (r != b.r)return r < b.r;return l > b.l;}
} a[210];
int sta[210], top, inv[1001000];
vector<int> g[210];
struct P
{int xs[210], len;// 积分inline void integral(){for (int i = len; i >= 0; i--)xs[i + 1] = 1ll * xs[i] * inv[i + 1] % mod;xs[0] = 0;len++;}// 单点求值(点值)inline int eval(int x){int ss = 0;for (int j = 0, w = 1; j <= len; j++, w = 1ll * w * x % mod)(ss += 1ll * w * xs[j] % mod) %= mod;return ss;}
} dp[210][410], E, C, fz[210];
// dp[i][j]:第i个区间的第j个分段函数区间[j,j+1]的多项式函数表达式
// 注意:dp[i][j]是概率分布函数,即概率密度函数的积分
// 两个多项式函数卷积
P mul(P a, P b)
{P c;c.len = a.len + b.len;for (int i = 0; i <= c.len; i++)c.xs[i] = 0;for (int i = 0; i <= a.len; i++)for (int j = 0; j <= b.len; j++)(c.xs[i + j] += 1ll * a.xs[i] * b.xs[j] % mod) %= mod;return c;
}
int c[410][410];
// 反褶,f(x)->f(1-x)
// 虽然f(x)仅在[0,inf]上定义,但是也可以进行定义域的补充,使得它是一个奇函数
P reverseAndShift(P a)
{P b;b.len = a.len;for (int i = 0; i <= b.len; i++)b.xs[i] = 0;for (int i = 0; i <= a.len; i++)(b.xs[0] += a.xs[i]) %= mod, (b.xs[i] -= a.xs[i]) %= mod;return b;
}
// 叠加两个多项式函数
void add(P &a, P b)
{if (a.len < b.len)swap(a, b);for (int i = 0; i <= b.len; i++)(a.xs[i] += b.xs[i]) %= mod;
}
int d[410];
void dfs(int x)
{if (g[x].empty()){dp[x][0] = E, dp[x][1] = C, d[x] = 1;return;}dp[x][0] = C, d[x] = 0;for (int v : g[x]){dfs(v);// 各个子树的概率分布函数要和父节点进行卷积以进行合并// 即,当前这一段的概率分布函数为f1(x),现在需要乘到父节点概率分布函数的这一段上for (int z = 0; z <= max(d[x], d[v]); z++)fz[z] = mul(dp[x][min(z, d[x])], dp[v][min(z, d[v])]);d[x] = max(d[x], d[v]);for (int z = 0; z <= d[x]; z++)dp[x][z] = fz[z];}// 考虑对这个区间整体做一次卷积运算if (x){// 最右侧的区间平移dp[x][d[x] + 1] = dp[x][d[x]], d[x]++;// 其他区间由于对1卷积,因而等价于直接积分for (int i = 0; i <= d[x]; i++)dp[x][i].integral();// 前一区间跟后一区间的叠加for (int i = d[x]; i; i--)add(dp[x][i], reverseAndShift(dp[x][i - 1]));// 补足x->inf的时候概率分布函数=1的部分,增加新的一段分段dp[x][d[x] + 1] = C, d[x]++;}
}
const int T = 1000000;
int S(int x)
{int e = x % T;x /= T; // 查在哪个区间(分段函数)之中e = 1ll * e * inv[T] % mod;return dp[0][min(x, d[0])].eval(e);
}
int main()
{E.len = 1, E.xs[1] = 1;C.len = 0, C.xs[0] = 1;inv[1] = 1;for (int i = 2; i <= T; i++)inv[i] = mod - 1ll * inv[mod % i] * (mod / i) % mod;c[0][0] = 1;for (int i = 1; i <= 400; i++){c[i][0] = 1;for (int j = 1; j <= i; j++)c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;}scanf("%d%d%d", &n, &m, &t);for (int i = 1; i <= m; i++)scanf("%d%d", &a[i].l, &a[i].r);sort(a + 1, a + m + 1);for (int i = 1; i <= m; i++){while (top && a[sta[top]].l >= a[i].l)g[i].push_back(sta[top]), top--;sta[++top] = i;}for (int i = 1; i <= top; i++)g[0].push_back(sta[i]);dfs(0);for (int i = 1, l, r; i <= t; i++){scanf("%d%d", &l, &r);printf("%d\n", ((S(r) - S(l)) % mod + mod) % mod);}return 0;
}

C Beautiful Sequence

题意:给定长度为 n n n 的序列 { a } i = 1 n \{a\}_{i=1}^n {a}i=1n 的异或差分序列 { b } i = 1 n − 1 \{b\}_{i=1}^{n-1} {b}i=1n1,要求 { a } \{a\} {a} 不严格递增且数字范围都在 [ 0 , 2 30 − 1 ] [0,2^{30}-1] [0,2301] 的第 k k k 大的序列。 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106 1 ≤ k < 2 30 1 \le k < 2^{30} 1k<230

解法:不难注意到给定了异或差分数组后,确定了第一个数字就确定了整个数组。由于是异或操作,考虑分位处理。

从高到低的枚举第 k k k 个二进制位。这时考虑如何通过异或差分数组得到递增条件。如果 b i = 0 b_i=0 bi=0,则 a i = a i + 1 a_i=a_{i+1} ai=ai+1,符合条件;如果 b i = 1 b_i=1 bi=1,则必须有 0 = a i < a i + 1 = 1 0=a_i<a_{i+1}=1 0=ai<ai+1=1,要么就是更高的二进制位上已经能够明确分出大小。因而可以考虑维护一个 vector 表示这一段仍未分出大小,需要通过更低位去判断,而块间不需要判断。因而块内必须有 0 = a i < a i + 1 = 1 0=a_i<a_{i+1}=1 0=ai<ai+1=1。如果当前这个二进制位没有约束,则可以 0 , 1 0,1 0,1。否则就必须强制填 0 , 1 0,1 0,1。这样的第 k k k 大只需要把可以变化的位拿出来,将 k k k 进行二进制表示即可。复杂度 O ( n log ⁡ V ) \mathcal O(n \log V) O(nlogV)

#include <bits/stdc++.h>
#define fp(i, a, b) for (int i = a, i##_ = b; i <= i##_; ++i)
#define fd(i, a, b) for (int i = a, i##_ = b; i >= i##_; --i)using namespace std;
using ll = long long;
const int N = 1e6 + 5;
int n, k, a[N], w[30];
void Solve() {scanf("%d%d", &n, &k), --k;fp(i, 2, n) scanf("%d", a + i), a[i] ^= a[i - 1];vector<int> vec;vector<pair<int, int>> s = {{1, n}}, t;memset(w, -1, sizeof w);fd(j, 29, 0) {for (auto [l, r] : s) {int fg = 0;fp(i, l + 1, r) {if ((a[i] >> j & 1) != (a[l] >> j & 1)) {fp(k, i + 1, r)if ((a[k] >> j & 1) != (a[i] >> j & 1))return puts("-1"), void();int x = a[l] >> j & 1;if (w[j] != -1 && w[j] != x)return puts("-1"), void();w[j] = x, fg = 1;t.push_back({l, i - 1}), t.push_back({i, r});break;}}if (!fg) t.push_back({l, r});}s = t, t.clear();}int x = 0;fp(i, 0, 29) {if (w[i] == -1)x |= (k & 1) << i, k >>= 1;else x |= w[i] << i;}if (k) puts("-1");else {fp(i, 1, n) printf("%d%c", x ^ a[i], " \n"[i == n]);}
}
int main() {int t = 1;scanf("%d", &t);while (t--) Solve();return 0;
}

E Star Wars

题意:在一个无向图 G ( n , m ) G(n,m) G(n,m) 上,可能有重边。一次操作可以执行下面的其中一条:

  1. ( u , v ) (u,v) (u,v) 上连接一条边。
  2. 去除 ( u , v ) (u,v) (u,v) 连接的一条边。
  3. 修改 a u a_u au 权值。
  4. 查询 u u u 相邻节点 a v a_v av 的权值和。

操作次数 1 ≤ q ≤ 3 × 1 0 5 1 \le q \le 3\times 10^5 1q3×105 1 ≤ n , m ≤ 3 × 1 0 5 1 \le n,m \le 3\times 10^5 1n,m3×105

解法:对于这类维护周围点连接情况的题,很容易想到根号分治,对大点(度数大的点)和小点(度数小的点)进行分开考虑。

对于大点小点的划分,通常来说使用根号为界限——当度数小于 O ( n ) O\left(\sqrt n\right) O(n ) 时,可以暴力去搜周围的点,单次查询复杂度 O ( n ) O\left(\sqrt n\right) O(n );对于度数较大的点,由于边数有限(假设 n , m n,m n,m 同阶),这样大点数目本身较少,只有 O ( n ) O\left(\sqrt n\right) O(n ) 个。因而可以考虑对大点进行一些特殊的数据结构处理以快速维护。

对于本题,当维护点权值更新时,小点可以暴力外推到周围所有的点,更新它们的答案,让大点的答案被动被小点所更新;大点对大点也可以考虑暴力,因为大点本身不多;大点对小点则采取标记的方式,在大点处打上标记,让小点来被动查询大点的更新情况。

当边数发生变化时,需要动态调整大小点的划分,当一个小点连接大量的边后需要晋升为大点以加速操作。同时根据上述规则同步更新每个点到周围点的答案。

感谢HDU-T04的提交。

#include <bits/stdc++.h>
#define pb push_back
#define fir first
#define sec second
#define ll long long
using namespace std;
typedef pair<int, int> pii;
const int N = 3e5 + 10, K = sqrt(N);
// 块阈值为K
const int P = (1 << 30);
int n, q, tot, d[N], cnt[N];
ll w[N], res[N];
vector<pii> e[N], G[N];
map<int, int> mp[N];
int TOT;
map<int, int> idx;
void add(int x, int y, int id)
{if (d[x] >= K)G[y].pb({x, id});elsee[x].pb({y, id});
}
// 由小点晋升为大点
void upd(int x)
{for (auto E : e[x]){G[E.fir].pb({x, E.sec});if (cnt[E.sec])res[x] += w[E.fir];}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> n >> q;int lst = 0;while (q--){int opt, x, y;cin >> opt >> x, x ^= lst;if (!idx.count(x))idx[x] = ++TOT, x = TOT;elsex = idx[x];if (opt == 4){// 大点等于被动更新值+本地值if (d[x] >= K){cout << res[x] + w[x] << endl;lst = (res[x] + w[x]) % P;}else // 小点暴力搜周围的点{ll ans = w[x];for (auto E : e[x])if (cnt[E.sec])ans += w[E.fir];cout << ans << endl;lst = ans % P;}}else{cin >> y, y ^= lst;if (opt == 1){// 先维护边if (!idx.count(y))idx[y] = ++TOT, y = TOT;elsey = idx[y];if (x == y)continue;if (y < x)swap(x, y);int id;if (!mp[x].count(y)){mp[x][y] = ++tot, id = tot;add(x, y, id), add(y, x, id);}elseid = mp[x][y];cnt[id]++;if (cnt[id] == 1){// x为大点:被动更新if (d[x] >= K)res[x] += w[y];if (d[y] >= K)res[y] += w[x];}d[x]++, d[y]++;if (d[x] == K)upd(x);if (d[y] == K)upd(y);}else if (opt == 2){if (!idx.count(y))idx[y] = ++TOT, y = TOT;elsey = idx[y];if (x == y)continue;if (y < x)swap(x, y);int id = mp[x][y];cnt[id]--;if (!cnt[id]){// 回退if (d[x] >= K)res[x] -= w[y];if (d[y] >= K)res[y] -= w[x];}}else{w[x] += y;for (auto E : G[x])if (cnt[E.sec])res[E.fir] += y;}}}return 0;
}

F Counting Sequences

题意:问有多少个长度为 n n n 的序列 { A } = { a 1 , a 2 , ⋯ , a n } \{A\}=\{a_1,a_2,\cdots,a_n\} {A}={a1,a2,,an} 满足,它与自身循环右移一位的序列 { B } = { a 2 , a 3 , ⋯ , a n , a 1 } \{B\}=\{a_2,a_3,\cdots,a_n,a_1\} {B}={a2,a3,,an,a1} 异或得到的序列 { C } \{C\} {C} 中,每个数字二进制表示中 1 1 1 的数目有 k k k 个,且 0 ≤ a i < 2 m 0 \le a_i <2^m 0ai<2m 1 ≤ n < 998 244 353 1 \le n <998\ 244\ 353 1n<998 244 353 1 ≤ m ≤ 1 0 8 1 \le m \le 10^8 1m108 1 ≤ k ≤ 5 × 1 0 4 1 \le k \le 5\times 10^4 1k5×104

解法:由于是异或操作,因而每位独立。考虑对于一个特定的二进制位,原序列 { A } \{A\} {A} 与右移一位的 { B } \{B\} {B} 异或后得到的异或结果序列 { C } \{C\} {C} 性质,有:

  1. 一个异或结果序列对应于原来的两个序列。不难注意到 c i = a i + 1 ⊕ a i c_i=a_{i+1}\oplus a_i ci=ai+1ai,因而 { C } \{C\} {C} 等价于 { A } \{A\} {A} 的异或差分序列。如果设定 a 1 a_1 a1,则整个序列都可以通过逐步递推得到,并且 a 1 a_1 a1 任意。因而 a 1 a_1 a1 的两种取值对应于原序列的两种取值。
  2. 如果异或结果序列的 1 1 1 个数为奇数,则原序列无解。因为 c i = a i ⊕ a i + 1 c_i=a_i \oplus a_{i+1} ci=aiai+1(此处 a n + 1 = a 1 a_{n+1}=a_1 an+1=a1),则 ⨁ i = 1 n c i = ⨁ i = 1 n a i a i + 1 = 0 \bigoplus_{i=1}^n c_i=\bigoplus_{i=1}^n a_ia_{i+1}=0 i=1nci=i=1naiai+1=0,因为每个数字都出现了两次。因而 c i c_i ci 1 1 1 个数必然为偶数。

因而对于一个二进制位,异或结果序列在这一位上产生 k k k 1 1 1 的方案可以用一个多项式 f f f 表达:
f ( x ) = ∑ i = 0 ⌊ n 2 ⌋ 2 ( n 2 i ) x 2 i f(x)=\sum_{i=0}^{\left \lfloor \frac{n}{2}\right \rfloor} 2\binom{n}{2i}x^{2i} f(x)=i=02n2(2in)x2i
即,奇数个 1 1 1 的方案不存在,偶数个 1 1 1 的方案等价于在 n n n 个数中选出 k k k 个数字的方案乘以 2 2 2

由于此处需要计算 m m m 个二进制位上得到 1 1 1 个数总和为 k k k 的方案,由于各行独立,因而使用乘法原理将每一行的多项式乘起来,不难得到答案为 [ x k ] f m ( x ) [x^k]f^m(x) [xk]fm(x)。由于求的目标项系数仅为 k k k 次,因而进行快速幂的多项式 f f f 也不需要保留到 n n n 次,而仅需要 k k k 次即可,更高次项显然不会对答案有任何贡献。使用多项式快速幂(多项式 exp 和多项式 ln 配合)即可在 O ( k log ⁡ m ) \mathcal O(k \log m) O(klogm) 的复杂度内求解。

关于生成函数的一些基础知识,请参看附录·甲 生成函数入门部分。

int main()
{long long n, m, k;cin >> n >> m >> k;Poly f(k + 1);long long C = 1;for (int i = 0; i <= k; i++){if (i % 2 == 0)f[i] = C;C = C * (n - i) % P;C = C * inv[i + 1] % P;}Poly ans = f.pow(m, k + 1);long long cur = ans[k];printf("%d", cur * fpow(2, m) % P);return 0;
}

G Cyperation

题意:给定长度为 n n n 的环 { a } i = 1 n \{a\}_{i=1}^n {a}i=1n,每次可以选择环上最近距离为 k k k 的两点 i , j i,j i,j 使得 a i a_i ai a j a_j aj 都减 1 1 1。问能不能经过若干次操作让整个环上数字清零。多测, 1 ≤ T ≤ 1 0 6 1 \le T \le 10^6 1T106 2 ≤ ∑ n ≤ 1 0 6 2 \le \sum n \le 10^6 2n106 1 ≤ k ≤ n 1 \le k \le n 1kn

解法:首先特判全 0 0 0 k > ⌊ n 2 ⌋ k>\left \lfloor\dfrac{n}{2} \right \rfloor k>2n 的情况。首先可以考虑将能够一起操作的数字通过重新排列放置到一起,由于每个数字只能至多和两个数字一起减 1 1 1,因而必定可以成环。整个大环就可以分成若干个独立的小环单独处理。

这时考虑环 a 0 , a 1 , ⋯ , a k a_0,a_1,\cdots,a_k a0,a1,,ak,设 a 0 a_0 a0 a 1 a_1 a1 一起减了 x x x 次。则 a 1 a_1 a1 再想要减到 0 0 0 a 1 a_1 a1 就必须和 a 2 a_2 a2 一起减 a 1 − x a_1-x a1x 次,同理可以推得 a 2 a_2 a2 a 3 a_3 a3 一起减 a 2 − a 1 + x a_2-a_1+x a2a1+x 次,依次类推。

不难注意到每传递一轮 x x x 的系数正负号翻转一次。可以把环上这每个次数的一次函数表达式写出。显然这些次数都是非负数,因而维护一个合法的 x x x 区间 [ l , r ] [l,r] [l,r] 即可。同时,当环长为偶数时,经过一圈的递推可以得到 a 0 a_0 a0 a 1 a_1 a1 要一起减 x + b x+b x+b 次。如果 b ≠ 0 b \ne 0 b=0 则无解;如果环长为奇数,则一圈递推后 a 0 a_0 a0 a 1 a_1 a1 的次数为 b − x b-x bx。这时需要满足 2 x = b 2x=b 2x=b,可以解出固定的整数 x x x b b b 为奇数则直接无解)。带入检查这个 x x x 是否合法即可。

#include <bits/stdc++.h>
#define fp(i, a, b) for (int i = a, i##_ = int(b); i <= i##_; ++i)
#define fd(i, a, b) for (int i = a, i##_ = int(b); i >= i##_; --i)using namespace std;
using ll = long long;
const int N = 2e6 + 5;
ll a[N];
int n, k, vis[N];
void Clear() { fp(i, 0, n - 1) vis[i] = 0; }
struct node {ll a, b;node operator-(const node &x) const{return {a - x.a, b - x.b};}node operator+(const node &x) const{return {a + x.a, b + x.b};}
};
bool Checker(vector<long long> &num) {int m = num.size();vector<node> cur(m);cur[0] = (node){1ll, 0ll};ll l = 0, r = num[0];fp(i, 0, m - 1)cur[(i + 1) % m] = (node){0ll, num[(i + 1) % m]} - cur[i];fp(i, 0, m - 1)if (cur[i].a == -1) // -x+b>=0 x<=br = min(r, cur[i].b);else if (cur[i].a == 1) // x+b>=0 x>=-bl = max(l, -cur[i].b);else assert(false);if (m % 2) {if (cur[0].b % 2)return false;ll x = cur[0].b / 2;// printf("CUR X:%lld\n", x);if (x < l || x > r)return false;}else {if (cur.back().b != num[0])return false;}return l <= r;
}
void Solve() {scanf("%d%d", &n, &k);fp(i, 0, n - 1) scanf("%lld", &a[i]);bool zero = 1;fp(i, 0, n - 1) if (a[i]) zero = 0;if (zero) return (void)puts("YES");if (k > n / 2)return (void)puts("NO");bool fg = true;fp(i, 0, n - 1)if (!vis[i]) {vector<long long> cur;int pos = i;while (!vis[pos]) {cur.push_back(a[pos]);vis[pos] = 1;pos = (pos + k) % n;}fg &= Checker(cur);}if (fg) puts("YES");else puts("NO");
}
int main() {int t = 1;scanf("%d", &t);while (t--) Solve(), Clear();return 0;
}

I We Love Strings

题意:给定 n n n 个仅含 0,1,? 的正则串,? 可以匹配一个 01,问有多少个 01 串可以被至少一个正则串匹配。 1 ≤ n ≤ 400 1 \le n \le 400 1n400 ∑ ∣ s i ∣ ≤ 400 \sum |s_i| \le 400 si400

解法:由于 ∑ ∣ s i ∣ ≤ 400 \sum |s_i| \le 400 si400,不难想到根号分治——首先根据串长对串进行分类。对于串长小于等于 20 20 20 的,可以考虑直接枚举这 2 k 2^k 2k 个串,依次观察是否和这些正则串匹配;当串长长的时候,正则串个数不多。这时可以用 f S f_{S} fS 表示至少满足 S S S 集合内的正则串的串个数是多少。暴力计算 f S f_S fS——枚举有哪些正则串,然后逐位合并。然后使用类似与卷积的容斥递推得到恰好仅满足该集合内的串个数是多少。最后统计对非空集合求和即可。复杂度 O ( n 2 n ) \mathcal O\left(n2^{\sqrt n}\right) O(n2n )

#include <bits/stdc++.h>
using namespace std;
const int N = 400, LIM = 20, P = 998244353;
string s[N + 5];
long long th[N + 5];
class Solution
{vector<string> p;long long bigSolver(int len, int size){vector<long long> f(1 << size);f[0] = th[len];string base = "";for (int j = 0; j < len; j++)base += "?";for (int i = 1; i < 1 << size; i++){string cur = base;bool flag = 1;for (int j = 0; j < size && flag; j++)if (i >> j & 1){for (int k = 0; k < len; k++)if (p[j][k] != '?'){if (cur[k] == '?')cur[k] = p[j][k];else if (cur[k] != p[j][k]){flag = 0;break;}}}if (flag)f[i] = th[count(cur.begin(), cur.end(), '?')];}for (int i = 0; i < 1 << size; i++)for (int j = 0; j < size; j++)if (i >> j & 1)f[i ^ (1 << j)] = (f[i ^ (1 << j)] - f[i] + P) % P;long long ans = 0;for (int i = 1; i < 1 << size; i++)ans = (ans + f[i]) % P;return ans;}long long smallSolver(int len){long long ans = 0;for (int i = 0; i < 1 << len; i++){bool flag = 0;for (auto x : p){bool cur = 1;for (int j = 0; j < len; j++){if (x[j] == '?')continue;if (x[j] != (i >> j & 1) + '0'){cur = 0;break;}}if (cur){flag = 1;break;}}if (flag)ans++;}return ans;}public:void insert(string s){p.push_back(s);}long long query(){if (p.empty())return 0;int len = p[0].length();if (len <= LIM)return smallSolver(len);elsereturn bigSolver(len, p.size());}
} S[N + 5];
int main()
{th[0] = 1;for (int i = 1; i <= N; i++)th[i] = th[i - 1] * 2 % P;int n;scanf("%d", &n);for (int i = 1; i <= n; i++){cin >> s[i];S[s[i].length()].insert(s[i]);}long long ans = 0;for (int i = 1; i <= N; i++)ans = (ans + S[i].query()) % P;printf("%lld", ans);return 0;
}

K Set

题意:给定长度为 n n n 的序列 { a } i = 1 n \{a\}_{i=1}^n {a}i=1n,求下式:
∑ S ⊆ { a } i = 1 n ∣ S ∣ ( min ⁡ x ∈ S x ) ( max ⁡ y ∈ S y ) ( ⨁ z ∈ S z ) \sum_{S \subseteq \{a\}_{i=1}^n} |S|\left(\min_{x \in S}x\right)\left(\max_{y \in S}y\right)\left (\bigoplus_{z \in S}z\right) S{a}i=1nS(xSminx)(ySmaxy)(zSz)
1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106 0 ≤ a i < 2 30 0 \le a_i < 2^{30} 0ai<230

解法:首先对序列排序,那么考虑固定区间左右端点就可以确定 min ⁡ \min min max ⁡ \max max。由于出现异或,仍然考虑在这一位上拆位计算,即:
∑ k = 0 29 2 k ∑ S ∈ { a } i = 1 n ∣ S ∣ ( min ⁡ x ∈ S x ) ( max ⁡ y ∈ S y ) [ [ 2 k ] ( ⨁ z ∈ S z ) = 1 ] \sum_{k=0}^{29} 2^k \sum_{S \in \{a\}_{i=1}^n} |S|\left(\min_{x \in S}x\right)\left(\max_{y \in S}y\right)\left[[2^k]\left(\bigoplus_{z \in S}z\right)=1\right] k=0292kS{a}i=1nS(xSminx)(ySmaxy)[[2k](zSz)=1]
考虑枚举右端点,观察所有区间异或和为 1 1 1 的左端点和集合大小的乘积。考虑用 f f f 数组维护所有合法方案中当前异或和是 0 0 0 还是 1 1 1 min ⁡ x \min x minx 的和, g g g 数组表示所有合法方案的 ∣ S ∣ min ⁡ x |S|\min x Sminx 的和,进行递推。

每当加入一个数字 k k k,假设当前它在这一位上二进制位是 y y y,那么对于 f f f(截至目前枚举到的数字中,所有合法选择状态下 min ⁡ x \min x minx 的和)的更新,有三种情况:

  1. 仅选择当前数字。则 f y ← k f_y \leftarrow k fyk
  2. 不选择当前数字。则 f 0 ← f 0 f_0 \leftarrow f_0 f0f0 f 1 ← f 1 f_1 \leftarrow f_1 f1f1
  3. 之前所有的方案加入当前的数字,则 min ⁡ x \min x minx 本身不变,但是所有方案下 min ⁡ x \min x minx 的和发生变化。则新的 f 0 ← f x f_0 \leftarrow f_x f0fx f 1 ← f x ⊕ 1 f_1 \leftarrow f_{x \oplus 1} f1fx1

对于 g g g,同样分为这三类:

  1. 仅选择当前数字。则 g y ← k × 1 g_y \leftarrow k\times 1 gyk×1
  2. 不选择当前数字。则 g 0 ← g 0 g_0 \leftarrow g_0 g0g0 g 1 ← g 1 g_1 \leftarrow g_1 g1g1
  3. 之前所有的方案加入当前的数字,则 ∣ S ∣ min ⁡ x |S|\min x Sminx 本身要变成 ( ∣ S ∣ + 1 ) min ⁡ x (|S|+1)\min x (S+1)minx。则新的 g 0 ← f x + g x g_0 \leftarrow f_x+g_x g0fx+gx g 1 ← f x ⊕ 1 + g x ⊕ 1 g_1 \leftarrow f_{x \oplus 1}+g_{x \oplus 1} g1fx1+gx1

按照上式递推更新即可。总复杂度 O ( n log ⁡ V ) \mathcal O(n \log V) O(nlogV)

#include <bits/stdc++.h>
#define fp(i, a, b) for (int i = a, i##_ = b; i <= i##_; ++i)
#define fd(i, a, b) for (int i = a, i##_ = b; i >= i##_; --i)using namespace std;
using ll = long long;
const int N = 1e6 + 5, P = 998244353;
int n, a[N];
void Solve() {scanf("%d", &n);fp(i, 1, n) scanf("%d", a + i);sort(a + 1, a + n + 1);int ans = 0;fp(j, 0, 30) {vector<ll> f = {0, 0}, g = f, w;fp(i, 1, n) {int x = a[i] >> j & 1, sum;w = {0, 0}, w[x] = a[i], sum = (w[1] + f[x ^ 1] + g[x ^ 1]) % P;ans = (ans + (1ll << j) * a[i] % P * sum) % P;g = {(g[0] + w[0] + f[x] + g[x]) % P, (g[1] + sum) % P};f = {(f[0] + w[0] + f[x]) % P, (f[1] + w[1] + f[x ^ 1]) % P};}}printf("%d\n", ans);
}
int main() {int t = 1;// scanf("%d", &t);while (t--) Solve();return 0;
}

L Misaka Mikoto’s Dynamic KMP Problem

题意:给定串 S S S,一次操作可以执行下面的其中一条:

  1. 修改 S S S 中一个字符。
  2. 给定串 T T T,问 S S S T T T 中出现多少次,以及 S S S 的 border 长度。输出它们的乘积。

操作次数 1 ≤ q ≤ 1 0 6 1 \le q \le 10^6 1q106 ∑ ∣ T ∣ , S ≤ 2 × 1 0 6 \sum |T|,S \le 2\times 10^6 T,S2×106。强制在线。

解法:这题最大需要注意到的点就是输出的是匹配次数乘以 border 长度。因而当 ∣ t ∣ < ∣ s ∣ |t|<|s| t<s 时,border 长度是无需计算的因为匹配次数必然为 0 0 0;而当 t t t 长的时候,暴力匹配 s s s t t t,由于限制了 ∑ ∣ t ∣ \sum |t| t,因而这样暴力执行计算的次数不会很多,至多每次 ∣ t ∣ = ∣ s ∣ |t|=|s| t=s。这样总复杂度仅为 O ( 2 ∑ ∣ T ∣ ) \mathcal O\left(2\sum |T|\right) O(2T)

#include <bits/stdc++.h>
using namespace std;
class KMP
{vector<int> nx;vector<long long> b;public:KMP(vector<long long> &b){this->b = b;int n = b.size();int j = 0;nx.resize(n);for (int i = 1; i < n; i++){while (j > 0 && b[i] != b[j])j = nx[j - 1];if (b[i] == b[j])j++;nx[i] = j;}}int find(vector<long long> &a){int n = b.size(), m = a.size();int j = 0;long long ans = 0;for (int i = 0; i < m; i++){while (j > 0 && a[i] != b[j])j = nx[j - 1];if (a[i] == b[j])j++;if (j == n){//匹配位点:i-n+1ans++;j = nx[j - 1];}}return ans;}int getBorder(){return nx.back();}
};
int main()
{long long b, mod, x, pos;int n, q, op;scanf("%d%d%lld%lld", &n, &q, &b, &mod);vector<long long> s(n);for (int i = 0; i < n; i++)scanf("%lld", &s[i]);long long cur = 1, ans = 0, lastans = 0;while (q--){scanf("%d", &op);if (op == 1){scanf("%lld%lld", &pos, &x);s[(pos ^ lastans) % n] = x ^ lastans;}else{cur = cur * b % mod;scanf("%lld", &pos);vector<long long> t(pos);for (auto &x : t){scanf("%lld", &x);x ^= lastans;}if (t.size() < s.size()){lastans = 0;continue;}KMP solve(s);lastans = 1ll * solve.find(t) * solve.getBorder();ans = (ans + lastans % mod * cur % mod) % mod;}}printf("%lld", ans);return 0;
}

M Writing Books

题意: q q q 次询问 [ 1 , n ] [1,n] [1,n] 中数位个数的和。 1 ≤ q ≤ 1 0 5 1 \le q \le 10^5 1q105 1 ≤ n ≤ 1 0 9 1 \le n \le 10^9 1n109

解法:枚举 [ 1 0 k , 1 0 k + 1 − 1 ] [10^k,10^{k+1}-1] [10k,10k+11],这里面每个数字数位个数都是 k k k。枚举 k ∈ [ 1 , 9 ] k \in [1,9] k[1,9] 即可。复杂度 O ( q log ⁡ V ) \mathcal O(q \log V) O(qlogV)

#include <bits/stdc++.h>
#define fp(i, a, b) for (int i = a, i##_ = b; i <= i##_; ++i)
#define fd(i, a, b) for (int i = a, i##_ = b; i >= i##_; --i)using namespace std;
using ll = long long;
const int N = 2e5 + 5;
int n; ll f[10];
void Solve() {ll x, k = 0, i = 10;scanf("%lld", &x);for (; i <= x; i *= 10, ++k);// printf("%d %d %lld\n", k, x - i / 10 + 1, f[k - 1] + (x - i / 10 + 1) * (k + 1));printf("%lld\n", f[k - 1] + (x - i / 10 + 1) * (k + 1));
}
int main() {f[0] = 9;for (ll i = 1, k = 90; i <= 9; ++i, k *= 10)f[i] = f[i - 1] + (ll)k * (i + 1);// fp(i, 0, 9) printf("%lld ", f[i]);puts("");int t = 1;scanf("%d", &t);while (t--) Solve();return 0;
}

附录

在阅读下列背景知识前,最好有一些 信号与系统 的背景知识。

甲 生成函数入门

在研究离散时间信号的时候,会提到一种变换:Z 变换。对于一个单边离散时间信号 f ( t ) f(t) f(t),会定义它的 Z 变换为 Z ( z ) = ∑ i = 0 + ∞ f ( i ) z i \mathscr Z(z)=\displaystyle \sum_{i=0}^{+\infty} f(i)z^i Z(z)=i=0+f(i)zi,用一个函数来维护一个序列的性质。

考虑用一个函数来维护序列。首先考虑一个最基本的问题:

一个盒子中有 n n n 个完全相同的球,从中拿出 k k k 个球的方案数是多少?

这个问题的答案是显然的: ( n k ) \displaystyle \binom{n}{k} (kn)。当 k = 0 k=0 k=0 时答案是 ( n 0 ) \displaystyle \binom{n}{0} (0n) k = 1 k=1 k=1 时答案为 ( n 1 ) \displaystyle \binom{n}{1} (1n),依次类推。考虑把 k = 0 , 1 , ⋯ , n − 1 , n , n + 1 , ⋯ k=0,1,\cdots,n-1,n,n+1,\cdots k=0,1,,n1,n,n+1, 的答案记为一个数列 { f } \{f\} {f},可以得到:
( n 0 ) , ( n 1 ) , ⋯ , ( n k ) , ⋯ , ( n n − 1 ) , ( n n ) , 0 , 0 , ⋯ \binom{n}{0},\binom{n}{1},\cdots,\binom{n}{k},\cdots,\binom{n}{n-1},\binom{n}{n},0,0,\cdots (0n),(1n),,(kn),,(n1n),(nn),0,0,
如果我们不希望每次都书写这么长的序列来记录这个问题的答案,可以考虑引入一个新的符号 x x x——它不可以和一般的数字进行加减乘除计算,当且仅当 x x x 的指数相同的时候才可以进行系数的加减运算。和 Z 变换相同,我们进行同样的变化:
( n 0 ) x 0 + ( n 1 ) x 1 + ⋯ + ( n k ) x k + ⋯ + ( n n − 1 ) x n − 1 + ( n n ) x n + 0 x n + 1 + 0 x n + 2 ⋯ \binom{n}{0}x^0+\binom{n}{1}x^1+\cdots+\binom{n}{k}x^k+\cdots+\binom{n}{n-1}x^{n-1}+\binom{n}{n}x^n+0x^{n+1}+0x^{n+2}\cdots (0n)x0+(1n)x1++(kn)xk++(n1n)xn1+(nn)xn+0xn+1+0xn+2
这时我们会发现这个求和式可以使用二项式定理变成 ( x + 1 ) n (x+1)^n (x+1)n。因而我们这时就可以使用一个简单的函数 ( x + 1 ) n (x+1)^n (x+1)n 来去记录这个问题的一般答案。如果我们想知道这个序列的第 k k k 项,我们就可以去查询它的第 k k k 次项的系数,这个系数就表达了这个问题的答案。

但是引入这个记号还不足以带来足够的方便,我们希望这个式子它本身具有一定的组合意义。回到原问题: n n n 个盒子里面拿出 k k k 个球的方案,这时我们观察我们的 ( x + 1 ) n (x+1)^n (x+1)n,问题可以等价变换于——给定 n n n 个括号,每个括号里面可以选择 1 1 1 或者 x x x,问从这 n n n 个括号中选择 k k k x x x 的方案是什么。这两个问题显然完全等价,因而不难发现选 k k k x x x 的方案等价于 ( x + 1 ) n (x+1)^n (x+1)n x k x^k xk 项系数。我们尝试将 ( x + 1 ) n (x+1)^n (x+1)n 和我们的原问题进行映射。首先原问题中每个球取或者不取是相互独立的,且每个球只有取或者不取两种方案。而 ( x + 1 ) n (x+1)^n (x+1)n 中的乘法 ( x + 1 ) ⋅ ( x + 1 ) ⋯ ( x + 1 ) (x+1)\cdot(x+1)\cdots(x+1) (x+1)(x+1)(x+1) 本质对应于各个球取或者不取的独立性, x + 1 x+1 x+1 对应于当前球取或者不取的两种方案,只能二择其一。即多项式上定义的乘法运算,对应了乘法原理;而加法运算对应了加法原理。至此,任何排列组合问题都可以使用多项式上的这两种运算进行定义和表示。

通常来说,一般的计数问题得到的多项式函数是平凡的,不能用一些很简单的标记方法合并。但是使用 FFT、NTT 等 O ( n log ⁡ n ) \mathcal O(n \log n) O(nlogn) 的时间复杂度优秀的多项式卷积算法就可以快速计算一些卷积递推式,以达到快速计算的目的。

乙 乘积、卷积

在信号上,严格定义的多项式(离散时间信号)乘积和卷积运算如下:

  1. 乘积:
    f ( x ) ⋅ g ( x ) = f ( x ) g ( x ) = ∑ i = − ∞ + ∞ f i g i x i f(x)\cdot g(x)=f(x)g(x)=\sum_{i=-\infty}^{+\infty}f_ig_ix^i f(x)g(x)=f(x)g(x)=i=+figixi

  2. 卷积:
    f ∗ g ( x ) = ∫ − ∞ + ∞ f ( τ ) g ( x − τ ) d τ = ∑ i = − ∞ + ∞ ∑ j = − ∞ + ∞ f j g i − j x j f*g(x)=\int_{-\infty}^{+\infty}f(\tau)g(x-\tau){\rm d}\tau=\sum_{i=-\infty}^{+\infty}\sum_{j=-\infty}^{+\infty}f_jg_{i-j}x^j fg(x)=+f(τ)g(xτ)dτ=i=+j=+fjgijxj

不难看出,我们日常使用的多项式乘积运算本质对应于多项式卷积运算,而乘积其实实际上是各项系数一一相乘。之所以通常的乘积其实是用卷积算出来的,是因为数字的乘积本质是一个 x = 10 x=10 x=10 的多项式卷积——如 232 × 147 = ( 2 x 2 + 3 x + 2 ) ( x 2 + 4 x + 7 ) ∣ x = 10 232\times 147=(2x^2+3x+2)(x^2+4x+7)|_{x=10} 232×147=(2x2+3x+2)(x2+4x+7)x=10,而且 x k x^k xk 系数得到也是通过 ∑ i = 0 k x i x k − i \displaystyle \sum_{i=0}^k x^ix^{k-i} i=0kxixki 逐项乘起来然后相加得到的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/33973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PhotoShop学习笔记

PhotoShop学习笔记 对图像进行缩放拉伸自动选中像素相近的同一个区域分离图层的选中区域分离图层的非选中区域处理不自然的缝合痕迹 记录一些PhotoShop中用到的操作&#xff0c;主要是在处理AI图像时遇到的需求。 对图像进行缩放拉伸 CTRLT 自动选中像素相近的同一个区域 魔…

Easys Excel的表格导入(读)导出(写)-----java

一,EasyExcel官网: 可以学习一些新知识: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 二,为什么要使用easyexcle excel的一些优点和缺点 java解析excel的框架有很多 &#xff1a; poi jxl,存在问题&#xff1a;非常的消耗内存&#xff0c; easyexcel 我们…

获取历史dokcer镜像项目,并上传gitlab,再打包镜像管理

今天遇到一个问题&#xff1a; 发现一个部署在Jenkins的脚本用的docker镜像是&#xff1a;test_project:v20191108&#xff0c;即这个项目是19年的一个版本&#xff0c;由于代码不断更新&#xff0c;用现在的最新代码运行该脚本&#xff0c;可能不能运行了&#xff0c;必须用19…

Linux 基础(七)常用命令 - 磁盘分区命令

磁盘分区命令 磁盘相关命令dudffreetree 分区相关命令查看设备挂载明细挂载/卸载 分区挂载卸载持久挂载 分区查看当前分区详情对硬盘分区分区为新分区构建文件系统给新分区挂载一个目录 常见文件系统类型 磁盘相关命令 du 查看目录或者文件占用&#xff1b;默认会递归查询子目…

基于扩频的数字视频水印嵌入和检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................. for j 1:length(attens…

OpenCV实例(八)车牌字符识别技术(三)汉字识别

车牌字符识别技术&#xff08;三&#xff09;汉字识别 1.代码实例2.遇到问题3.汉字识别代码实例 相较于数字和英文字符的识别&#xff0c;汽车牌照中的汉字字符识别的难度更大&#xff0c;主要原因有以下4个方面&#xff1a; (1)字符笔画因切分误差导致非笔画或笔画流失。 (2…

安装使用IDEA,修改样式,配置服务,构建Maven项目(超级详细版)

目录 前言&#xff1a; 一&#xff0c;安装 1.1打开官网JetBrains: Essential tools for software developers and teams点击 Developer Tools&#xff0c;再点击 Intellij IDEA 2.点击下载​编辑 3.选择对应的版本&#xff0c;左边的 Ultimate 版本为旗舰版&#xff0c;需要…

阿里云服务器搭建Magento电子商务网站图文教程

本文阿里云百科分享使用阿里云服务器手动搭建Magento电子商务网站全流程&#xff0c;Magento是一款开源电商网站框架&#xff0c;其丰富的模块化架构体系及拓展功能可为大中型站点提供解决方案。Magento使用PHP开发&#xff0c;支持版本范围从PHP 5.6到PHP 7.1&#xff0c;并使…

MySQL数据库表的增删查改 - 进阶

一&#xff0c;数据库约束 1.1 约束对象 not null - 该列不能为空unique - 保证该列的每一行都不一样default - 规定没有给列赋值时的默认值&#xff08;自定义&#xff09;primary key - not null 和 unique 的结合&#xff0c;会给该列添加一个索引&#xff0…

CSS3 新特性

圆角阴影文字阴影线性渐变变换&#xff08;transform&#xff09;背景rgba伪元素&#xff1a;伪类 伪元素区别动画&#xff08;animate&#xff09;

中科亿海微浮点数转换定点数

引言 浮点数转换定点数是一种常见的数值转换技术&#xff0c;用于将浮点数表示转换为定点数表示。浮点数表示采用指数和尾数的形式&#xff0c;可以表示较大范围的数值&#xff0c;但存在精度有限的问题。而定点数表示则采用固定小数点位置的形式&#xff0c;具有固定的精度和范…

走进知识图谱(二)【世界知识图谱篇】知识表示的经典模型与平移模型及基于复杂关系建模的知识表示学习

上篇文章提到&#xff0c;该系列文章将主要围绕世界知识图谱和语言知识图谱这两大类知识图谱进行展开&#xff0c;并且提到知识图谱的主要研究包括了知识表示学习、知识自动获取和知识的推理与应用三大部分。今天主要介绍世界知识图谱的知识表示学习&#xff0c;其中包括经典的…

Android 13 Launcher——长按图标弹窗内容修改以及小组件等隐藏起来

目录 一.背景 二.实现思路 三.布局文件修改 四.隐藏代码中原先的view 一.背景 由于定制化开发需要将原先的长按图标原生弹窗界面隐藏,然后显示自定义的弹窗界面,如下就是我们来实现自定义的弹窗界面

redis Set类型命令

Redis中的Set是一种无序、不重复的集合数据结构&#xff0c;它提供了一系列的操作命令用于对Set进行添加、删除和查找等操作。以下是Redis中Set类型常见的一些命令&#xff1a; SADD key member [member …]&#xff1a;将一个或多个成员添加到指定的集合中。 示例&#xff1a;…

day-18 代码随想录算法训练营(19)二叉树 part05

513.找树左下角的值 思路一&#xff1a;层序遍历&#xff0c;每一层判断是不是最后一层&#xff0c;是的话直接返回第一个; 如何判断是不是最后一层呢&#xff0c;首先队列头部&#xff0c;其次记录左右子节点都没有的节点数是不是等于que.size()&#xff1b;或…

【ARM 嵌入式 编译系列 6 -- GCC objcopy, objdump, readelf, nm 介绍】

文章目录 GCC objcopy 简介objcopy 常用参数 GCC objdump 简介GCC readelf 介绍GCC nm 介绍 GCC objcopy 简介 objcopy 是 GNU二进制工具集(binutils)的一部分&#xff0c;主要用于复制和转换目标文件。 在ARM GCC中&#xff0c;arm-none-eabi-objcopy通常用于从链接后的ELF格…

C语言 字符指针

1、介绍 概念&#xff1a; 字符指针&#xff0c;就是字符类型的指针&#xff0c;同整型指针&#xff0c;指针指向的元素表示整型一样&#xff0c;字符指针指向的元素表示的是字符。 假设&#xff1a; char ch a;char * pc &ch; pc 就是字符指针变量&#xff0c;字符指…

数据库--数据类型

数据库相关链接&#xff1a; 数据库基础操作--增删改查&#xff1a;http://t.csdn.cn/189CF 数据库--三大范式、多表查询、函数sql&#xff1a;http://t.csdn.cn/udJSG 数据类型 创建表的时候&#xff0c;我们在类型这里给出了不同的选项&#xff0c;比如有int &#xff0c;…

python num循环怎么从1开始

如何实现python for循环从1开始&#xff1f; range()函数的作用和用法&#xff1a; 编写一个从数值1开始的循环&#xff1a; 执行后得到的结果 其他注意事项