Page Top

刷题记录——小笔记 慢慢更新

刷题记录——小笔记 慢慢更新

截止到:20240119(有时会忘记改日期)。

信友队——CSP-S 2023 复赛模拟赛

T2 忘了取模和二分了,直接爆 longlong 和 TLE 然后 \(0\text{pts}\).

CF1065C Make It Equal

桶桶桶桶桶!!!\(2e5\) 你不用桶难道还要二分的吗?

洛谷 CSP-S 2023 模拟赛

\(998244353\) 意义下的乘法一定要开 longlong!!!

要记住:\(998244352\times998244352=996491786299899904\)

市南集训

T2 哈希算阶乘别忘了取模!!!

frac[i] = frac[i - 1] * P;     // WA
frac[i] = frac[i - 1] * P % M; // AC

永远不要相信出题人!哈希取模永远不要相信 \(998244353\)\(19260817\)!永远不要相信自然溢出!永远不要偷懒写一个哈希!无论多水也必须写两个哈希!\(10^9+7\oplus10^9+9\) YYDS!

2023年码谷提高组模拟赛1016

存图,每条边存 \(2\) 遍然后开 \(1\times N\) 的数组 \(\texttt{RE}\)

\(\texttt{queue}\) 跑 BFS 忘 pop。

2023年码谷提高组模拟赛1018

一个树、图,无限大,一般是数学思想。

分段打表,已记录。

在图上,多组询问,每次选择小于、大于给定值的。可以将询问离线下来,排序,然后一点点的加边。

可以使用并查集维护,等等。

ABC324C

双指针跑[一个不同字符的]字符串匹配!不要相信吸氧的 \(\texttt{substr}\)

删除 \(\text{debug}\) 的时候不要忘记删去 \(\texttt{continue;}\)

精度要求 \(10^{-9}\),开 \(\text{eps}=\texttt{1e-5}\),要精度不要复杂度 \(\texttt{TLE}\)

正难则反——问满足条件 \(A\) 的里面有多少满足条件 \(B\) 的,可以等价转换为满足条件 \(B\) 的里面有多少满足条件 \(A\) 的,只需要找数量少或容易实现的做即可,可以枚举或 \(\texttt{...}\)

ABC251D

若干个数,\(+,\vee,\wedge\) 构造数字的,考虑 \(10/2\) 进制。

CF620E

\(\texttt{1<<n}\rightarrow\texttt{1ll<<n}\)

线段树的易错点:

  1. 搞清楚转移范围:\([l,r]\Rightarrow[l,\text{mid}]+[\sout{\text{mid}}\text{ mid}+1,r]\)
  2. 搞清楚 \(\texttt{push}\) 啥,一般来说,\(\texttt{mark}\) 记录这个区间被修改为/加上多少,\(\texttt{push}\) 只能把数据转移到子节点,不覆盖本节点,即 s[k * 2] = s[k * 2 + 1] = mark[k]; mark[k * 2] = mark[k * 2 + 1] = mark[k]; mark[k] = 0;,因此在函数中调用 \(\texttt{push}\) 也一定在所有条件判断完之后,即 if (l > q || r < p) return 0; if (l >= p && r <= q) return s[k]; push(k);
  3. 千万不要忘记 \(\texttt{build}\),除非初始值全为 \(0\)
  4. 要开 \(3\) 倍空间!!!

abc325

分层图最短路,如果只有 \(2\) 层,可以 \(\mathcal{O}(n)\) 的枚举。

ABC321F

看到「总和为 \(k\)」要想到背包。

CF1312E

总结: 对于比较难的 DP 题往往不以题面所要求的目标作为目标,而是进行一些目标的转换。一般有以下两种情况:

  • 利用容斥,取题面目标的反面。
  • 将要想求得题面目标所需要处理的信息进行处理。

比如先求解某组过程数据,然后再根据这组数据求解答案。

[The 2023 ICPC AROC I] G Spanning Tree

求生成指定生成树的概率,其实也就是 \(1/\)生成树个数,前提是该生成树合法。

而生成树个数可以表示为,每次合并集合时,两侧集合大小的乘积,即 \(\prod_{(l,r)\in\mathit{op}}\mathit{cnt}_l\times\mathit{cnt}_r\)

abc326_f

虽然 vector、bitset 很方便,但是卡常的时候还是会慢至少 1 倍的!

不要吝啬使用位运算。

但是一定要在纸上划拉划拉怎么状压。

尤其是从高位,还是低位开始存。

P1580 yyy loves Easter_Egg I

注意,Linux 下 cin、scanf 会读入换行符 (\n),而 Windows 下不会。

P4872 OIer们的东方梦

在矩阵、方格上跑(分层)最短路,可以不用把图建出来,省空间。

P9753 [CSP-S 2023] 消消乐

常用的哈希模数:

  • \(998244353\)\(19260817\):太常见,容易被卡。
  • \(10^9+7\)\(10^9+9\):太小,冲突概率较高。
  • \(8942221889969\):推荐,不过不好背。

CF437C The Child and Toy

在图中删点转换为删去与它相邻的边。

与被删点相邻的点转换为边的两个节点。

即每条边一定只被一个点删去,考虑是它的两个节点的哪一个即可。

ABC327

Math 库里的函数,int 可以直接用(排除掉速度。long long 需要用 long double 或者 llong 版本的,比如 powl。因为 double 精度达不到 1e18.

选若干个物品,最大、最小化贡献和。分数贡献的,如果选相同数目,分母不变用 0/1 背包处理分子,然后再统计结果。如果分母变了,用分数规划。

qbxt-1

花硬币问题,以标准货币:

  1. 要剩最少,用面额小的;
  2. 数量最小,用面额大的。

qbxt-2

巨大的数学题,要么暴力,要么不做。

qbxt-3

\(\mathit{mex}\) 可以 \(\mathcal{O}(n)\) 也可以 \(\mathcal{O}(v)\)

数论题不要做。除非搜索。生日悖论不会就胡一个。

写出来 BFS 了,想想可不可以 01 BFS 或者 meet-in-the-middle(半分全列拳)。

qbxt-4

理论上 NOIP 不考 slope optimization。

qbxt-5

在一个集合里面选东西,可能是背包,或者状压。

一堆东西什么玩意的相同可以 dsu。

dp 转移成环,最优化的可以最短路,线性的可以高消。

qbxt-6

输入为二的整数幂的,一般有特殊性质。

括号序列:

  • 一个字符串,仅由 () 组成;
  • 如果 \(s\) 是合法括号序列,那么 \((s)\) 也是合法括号序列;
  • 如果 \(s,t\) 都是合法括号序列,那么 \(st\) 也是合法括号序列;
  • 空串 \(\varepsilon\) 也是合法括号序列。

判断:栈。

bool check(string s) {
    stack<char> op;
    for (char c : s) {
        if (c == '(') op.push(c);
        else if (op.empty() || op.top() != '(') return false;
        else op.pop();
    } return op.empty();
}

合法子序列:区间 DP。

auto dp = [&] (string s) {
    int n = int(s.size()); vvi f(n, vi(n));
    rep(i, n) f[i][i] = 1;
    for (int len = 2; len <= n; ++len)
    for (int l = 0; l + len - 1 < n; ++l) {
        int r = l + len - 1; f[l][r] = f[l + 1][r];
        if (s[l] == '(') for (int k = l + 1; k <= r; ++k)
        if (s[k] == ')') f[l][r] += 1ll * f[k][r] * (k == l + 1 ? 1 : f[l + 1][k - 1]);
    } return f;
};

qbxt-7

袋鼠吃稽核。

斜优也可以解决树上问题。

也就是 dfs 退出的时候把加进去的点 pop 出来。

看到 \(\infty\)\(\inf\)\(\mathit{inf}\)\(\text{INF}\) 果断放弃。

qbxt-8

无关或易处理的变量,先处理掉。

动态规划 yyds。

字符串处理子串、子序列,大部分是动态规划。

可以:

  • \(f(i):=\text{前 }i\text{ 个}\).
  • \(f(i):=\text{后 }i\text{ 个}\).
  • \(f(i):=\text{有 }i\text{ 个}\).
  • \(f(i):=\text{没 }i\text{ 个}\).

形式化题面,有的时候比题目背景还难懂欸。

qbxt-9

简单的数位 dp,有的时候可以直接数学方法解决。

各有优劣。一般是数位 dp 好想,数学方法好写。

qbxt-10

离线,一点点的加边。

CF817F MEX Queries

不要 \(\texttt{ll(1e18 + 1)}\),会掉精度;要 \(\texttt{ll(1e18) + 1}\)

问:\(\texttt{(long long)(1e18 + x) != (long long)(1e18)}\),最小的正整数 \(x\);答:\(65\)

ABC336E

1e18 最多 19 位数。
1e14 最多 15 位数!

ABC334E

动态维护连通块个数。加入一个点,如果这个点:

  • 与现有〇个连通块相连:连通块 +1;
  • 与现有一个连通块相连:连通块 +0;
  • 与现有两个连通块相连:连通块 -1;
  • 与现有三个连通块相连:连通块 -2;
  • 与现有四个连通块相连:连通块 -3;

AcWing 119. 袭击

手写 set、map 的判定的时候,

struct cmp_y {
	bool operator ()(const emm &a, const emm &b) const {
		return a.y < b.y;
	}
};

后面的 const 不可省略。

哈希函数同理,

struct my_hash {
  static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }

  size_t operator()(pair<uint64_t, uint64_t> x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x.first + FIXED_RANDOM) ^
           (splitmix64(x.second + FIXED_RANDOM) >> 1);
  }
};
posted @ 2023-10-20 09:57  RainPPR  阅读(28)  评论(0编辑  收藏  举报