【比赛】2023 CSP-S 备战

2023 CSP-S 备战

赛后总结

得分:90 + 35 + 0 + 0

  1. 惨烈……
  2. T1 看完题的瞬间发现是大水题,于是直接开打,结果 10min 中打完,调了 20min,最后同时拨相邻的情况还没改过来。
  3. T2 没有吸取 T1 的教训,甚至失误的更严重,感觉是个并查集,算法把样例手推过了之后,又花了 40min 多调试,大样例死活过不了。最后稍微细想了一下,就把这个做法 Hack 了。耽误太多时间,最后还是 5min 打了个很水的暴力。
  4. 当时心态其实就有点问题了,再加之电脑时间被调快了一个小时,心态更炸了,于是直接开了 “小有挑战” 的 T3。结果就是 T3,打到一半,电脑上时间已经交卷了(实际上还有 1 个小时),才发现时间快了,稍微稳住了一点,重新把 T3 的打法梳理了一遍,但最终还是没打完。(RE 0 pts)

考试策略

  1. 20min 左右通读题面(一定不要读错题,结合样例分析
  2. 每道题题至少保证 50pts 左右的暴力
  3. 不必按照顺序做题,那道题最有希望先做哪道

  1. 随时存盘
  2. 时间分配
    1. 注重暴力(特别是没有思路的时候,有时间就打
    2. 不要在没把握的的,耗费太长时间
  3. 80pts - 100pts 都可以认为是正解(不要优化常数
  4. 先想再写
  5. 对拍
    1. 好写的对拍哪怕是暴力也好写暴力
    2. 不要太以来大数据
    3. 对拍以验证正确性为目的(不要用于验证性能
  6. 重视静态差错
  7. 宁愿少开空间,也不要 MLE(算好空间
  8. 最后 15min 不要打新的代码(文件输入输出,
  9. 中途感觉前一半时间荒废了,不要再想以前浪费的时间了。调整好心态
  10. 及时调整预期得分
  11. 相信自己!!!

一些链接

备忘


知识点补漏

数学常用结论


\(\large\star\) KMP

  • \(nxt\) 数组的求法

    nxt[1] = 0;
    for (int i = 2; i <= n; i++) {
    	int j = nxt[i-1];
    	while (j && s[i] != s[j+1]) j = nxt[j];  // 记得这的 j 不须 -1
    	nxt[i] = j + (s[i] == s[j+1]);
    }
    
  • 时间复杂度证明:

    \(j\) 每次至少减少 1,而且减少总次数不会超过当前 \(j\) 增加总次数。而 \(j\) 最多增加 \(n\) 次,那么最多就减少 \(n\) 次,故时间复杂度为 \(O(n)\)


联通分量

  • low[i] 定义:在 本次dfs 已遍历过的点中,dfn 的最小值。

  • 板板

    void Tarjan (int u) {
    	st[++st[0]] = u, low[u] = dfn[u] = ++_dfn;
    	for (int v : G[u])
    		if (!dfn[v])
    			Tarjan(v),
    			low[u] = min(low[u], low[v]);
    		else if (!scc[v])  // !!! 如果 v 已经属于一个连通块内了,你还要去找她更新干嘛??? 
    			low[u] = min(low[u], dfn[v]);
    	if (low[u] == dfn[u]) {
    		++_scc;
    		do scc[st[st[0]--]] = _scc;
    		while (st[st[0]+1] != u);
    	}
    }
    
  • \(\large\star\) 缩点以后图当然是 DAG,但是不一定没有重边【最大半连通子图


最短路

CRT & ExCRT

卢卡斯 Lucas

\[\binom{n}{m}\bmod p = \binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\cdot\binom{n\bmod p}{m\bmod p}\bmod p \]

  • 需要 \(p\) 为质数。

Some Tricks

2023.10

  • nxt 的淫奇应用
  • 只要题目牵扯到 “连通性”,大概率就是要缩点(?
  • 边权仅为 \(1\) 的图,跑单源最短路,纯 bfs 的 \(O(n)\) 比 Dijkstra 的 \(O((n+m)\log n)\) 更优。【[CSP-S 2022] 假期计划
  • 可以先预处理一段的贡献,再统一做 DP 【[ZJOI2006] 物流运输
  • 输出程序空间的方法(from XSC062
Example
#include <bits/stdc++.h>
bool _bg;  // 程序的最开始 
using namespace std;
typedef long long ll;
int main () {
	// ... Code 
	bool _ed;  // 程序的最末尾 
	printf("%lf", (&_ed - &_bg) / 1024.0 / 1024.0);
	return 0;
}
  • 先写暴力 (dp) 再考虑优化。
    • 数据结构 处理带一定限制的 dp(直接排除一些不合法的更新值)【分糖果
    • 具体化成 网络、DAG 上问题,规整的网络图可以考虑递归处理【宝石加工
  • 正难则反(多用于计数类问题)【同色三角形
  • g++

考试总结

10.6 NKOI-S Round2

  • 不要觉得暴力只有十几二十分就不去拿【T4】
  • 数据范围并不总是提示做法,适合题目的才是最好的【T3】
  • 总要找时间去码代码,不要一直呆在那里想
  • 先做最有把握的题【T3】

10.14 NKOI-S Round4

  • 最好每道题都输出下空间(方法见 Trick)【T2】

10.19 NKOI-S Round6

  • 一道题不要卡太久【T1】

日常犯智

  1. Dinic 中,如果 rest\(0\),直接终止循环。(真的会快很多
Dinic
int dinic (int u, int flow) {
 	if (u == T) return flow;
 	int rest = flow;
 	for (int i = now[u]; i && rest; i = edge[i].nxt) {  //rest
 		now[u] = i;
 		int v = edge[i].v, c = edge[i].c;
 		if (c > 0 && d[v] == d[u] + 1) {
 			int k = dinic(v, min(rest, c));
 			if (!k) d[v] = 0;
 			rest -= k, edge[i].c -= k, edge[i^1].c += k;
 		}
 	}
 	return flow - rest;
 }
  1. fill() 的第二个参数应该指向末尾的下一个指针。

  2. \(\large\star\) 对于 \(ax+by=\gcd(a,b)\)Exgcd 求出的 \(x,y\)一定保证 \(x\) 最小,但不一定是正数,转为最小整数:(求逆元时一定要用)

\[p=b/\gcd(a,b),x\gets(x\%p+p)\%p \]

  1. Hash 时,求模数的若干次方时,\(P[0]\) 记得赋成 \(1\)
  2. (n>>1)+1 当然不等价于 n>>1|1 ……(比如 n=3 就 G 了【NKOI-S R3 T2
  3. 一些复杂条件的 if 嵌套,或者少写一个 vis 而用 dis 代替,不要为了少几行代码,写可能出锅的代码【最大半连通子图 & [CSP-S 2022] 假期计划
  4. 时间复杂度不能凭感觉算,\(2500\)\(O(n^2)\) 也是可以过的【[CSP-S 2022] 假期计划
  5. Dijkstra 的权值一定不能在从队列里面拿出来之后再更新(详见 90pts & 100pts 的代码【[SCOI2009] 最长距离
  6. (from jzb) 记得考虑除数为 \(0\) 的情况,否则如果是 double 的话会出现 inf
  7. 斜率优化注意是要 “后减前” 否则斜率算出来是负数,最小值求成最大值。
posted @ 2023-09-29 10:49  CloudWings  阅读(141)  评论(0编辑  收藏  举报