一些总结

距离 \(NOIP 2025\) 还有 \(1\)

十月以来做过的一些题目:(基本按照时间顺序给出)

ABC325G 小清新区间 \(DP\) ,然而看来我需要练习造 \(hack\)

P7801 \(SA\) 板子,复健使用,在 P1337 学会板子后尝试默写

P14140 线段树二分,半年前省选 \(D2T1\) 的线段树二分使得当时的蒟蒻倒闭了,不能在同一知识点再次倒闭

P7377 乱搞能力,信心题

ABC400G 实际难度并不很高的 \(DP\)(好吧复习的时候依旧倒闭了)

P8048 蚂蚁 的进阶,经典 \(trick\) 是碰撞掉头的同时也有灵魂互换,这样就没有转向什么事了(此外这道题 也有相似的 \(trick\)

P2048 \(RMQ\) 好题,静态问题中倍增思想历来是一种重要而容易被我忽视的考虑,上一道 \(AT\) 的图论同样没想到倍增,需要引起重视
(但是说双 \(log\) 的部分分可以简单用动态开点权值线段树实现,可以练习这两个板子的熟练度和打部分分的能力)

ARC075D 简单暴搜和一点点优化,然而没有独立完成,输(此外可以思考 \(d \le 10^{5000}\) 的加强版)

ARC082D 简单模拟,但是花了太多时间,没有tihnk twice code once导致的

CF1110D 简单 \(DP\) ,同上做的不够快,可能是久了没做 \(CF\) 的题,当然更可能是我菜

CF2107F2 容易胡出来是斜优,但是具体的推式子有一定难度

P5852 状态不太好的一天难得成功对上脑电波的题(然而下次不一定对的上)

P3250 难度中下的一道整体二分,适合刚学整体二分之后巩固

ARC073D 对我而言不很好想的 \(DP\) 式子

ABC217F 普通区间 \(DP\) ,然而我用一下午时间先后思考出了正解的两个部分而没想到正解

ABC158F 很好想的计数,让我产生了计数还有救的错觉

ABC262D 应该是这段时间做过最水的题之一了

P5815 不知道为什么一道水题想了写了一堆有的没的,反复强调要 think twice code once 然而实行了 \(0\) 次(自闭)

ARC120D 非常好玩的贪心

P9870 特殊性质启发正解和数形结合的典型例题

HDU4442 领项交换法简单例题(放的是 \(vjudge\) 链接)

P2824 思路很重要,没想到自己距离 \(NOIP\) 就三十多天了居然还是不会,重新意识到我大约的确真没救了,非常的倒闭

CF935E 简单括号序列建树和简单 \(DP\) ,适合忘了括号序列建树的时候回来复健

CF1625E2 复杂括号序列,建树的方式值得记忆,感觉这之前一直没有一种括号序列建树的一般方式

P9669 树上计数好题,自己完成了 \(80%\) 的思考过程,但是有一个系数没想到处理方式,于是一个上午倒闭了

P2700 并查集/树上 \(DP\) 都可以做的一道简单题

AT_icpc2013spring_e 会做次小生成树就会这道

P1967 同样生成树傻逼题

P4306 \(floyd\)\(bitset\) 优化,虽然很简单但是之前没见过,还是需要警惕一下

三进制数 一道不知道教练从哪找的题,但是还挺有趣

P9351 神秘,非常神秘,不好说哪种套路,纯考验思维,是我最怕的那种

ABC207F 无聊的换根计数 \(DP\)

P4926 啊这是[数据删除]?啊对数还能这样用?

P6852 推性质的能力显然太弱,以及都不想再写一遍什么退出错误思路之类的话了

P7339 贪心假掉了不仅要考虑换一种贪心,也要考虑本题根本不是贪心

搬箱子 同样一道不知道从哪找的题,但是思路很经典,处理模数非质数的组合数的思路也很经典,然后我发现自己居然不知道预处理质因数的范围,相当的倒闭

CF1325D 谁说看到位运算就一定要拆位了?明明有更美妙的性质

P7287 题目本身在思维题题单里不难,然而一定要注意二分的边界不可忽视,实在不行写个 \(2e9\) 再说

P6859 思维方面很巧妙,但是我会,因此我想说的重点是读入字符要小心和把调试代码删除干净(已分别单独记录)

ABC263F 个人感觉到不了声称的难度,可能是最近见过一些有关 \(2^n\) 序列的题?

ABC230F 妈呀我又有一个经典 \(trick\) 不会了

P7568 花了很长时间,依旧是想法很近但总是差那么一点的类型,感觉一是对“优化掉无用状态”这种东西不够敏感,难以想象或声称这样可以把程序效率直接整对,二就是根本上对于一些想法不敢实现了,只能每次见到都敲响警钟并希望自己考场上能克服这一点

ABC341F 依旧简单题,这道题和 \(263F\),\(230F\) 是同一晚上做的,你谷难度相同,但是 \(230F\) 花的时间的一半都比另外两道题时间加起来长,乐

P9433 竟然不会,寄

P6688 这种东西考虑到哈希是普遍的,关键在于怎么设计哈希

P14479 月赛题,倒着处理的思路很有启发性,还有就是 \(1e6\)\(STL::stack\) 的空间居然相当的倒闭,非常值得警惕

P4408 突击的一道在图论题单里的树,会做但是做的很慢,不知道考场上碰到图论会怎样

一些容易被忽视的公式:

$ gcd(a,b)=gcd(a-b,b) (a>b)$

\(n*C(n-1,m-1)=m*C(n,m)\)

$ \sum_{i=0}^{i\le n} C_{n}^{i} = 2^n $

$ C_{n}^0 + C_{n}^2 + C_{n}^4 +... = 2^{n-1} $,证明考虑二项式定理

$ C_n=\sum_{i=0}^{i\le n-1} C_i*C_{n-i-1} $ ( \(C\) 指卡特兰数)

插板法:

\(n\) 个外观相同的数分成 \(k\) 份,要求每一份均非空,等价于在 \(n-1\) 个空隙里插入 \(k-1\) 块板,方案数即为 \(C_{n-1}^{k-1}\)

如果允许出现某一份或几份为空,等价于先借 \(k\) 个元素来再分,方案数为 \(C_{n+k-1}^{k-1}\),显然也等于 \(C_{n+k-1}^n\)

第二类斯特林数:

\({n,k}\) => 把 \(n\) 个不同元素分成 \(k\) 份,要求每一份均非空,有公式:\({n,k}\) = \(\frac { \sum_{t=0}^{t\le k} (-1)^t*C_{k}^{t} * (k-t)^n}{k!}\)

虽然二项式反演是正招,但也可以理解为钦定 \(k\) 个盒子中 \(t\) 个为空做奇偶容斥,这样首先是 \(k\) 中选 \(t\) 的组合数,然后是 \(n\) 个数每个有 \((k-t)\) 种可能,最后因为盒子都一样所以除去 \(k\) 的阶乘

李善兰恒等式:\(\sum_{j=0}^{n} {\binom{n}{j}}^2=\binom{2n}{n}\) (知乎刷到的,我认为这是一种天意)

二项式定理:\((x+y)^n = \sum_{i=0}^{n} \binom{n}{i}*x^i*y^{n-i}\),证明显然,当 \(x=1\)\(y\) 为某些特殊值的时候可变化为各种式子

差分约束:(欸这也算公式吗)

若有形如 \(x_i \le x_j+w\) 的式子,则建边 \(add(j,i,w)\),然后跑最短路,负环则无解(大于等于可以移项,也可以考虑改最长路)固定了本题使用最短路/最长路之后就要把所有符号都化为 \(\le\)\(\ge\),原来的式子是乘除号用对数转成加减号

一些见过的经典转化:

砍一半后刚好数据可接受=>折半搜索(尤其是 \(n\le [30,36]\) 这个范围)

优化枚举顺序

区间问题通过差分/前缀和/只考虑端点处转单点

位运算=>拆位

算两次

建图=>有环且环没什么用=>简化为树(=>简化为链/菊花图)(例题)

给定某棵树=>树上有隐性边=>转成图(例题)

根号分治(例题)

计数/某点受多点限制:\(bitset\) 优化(例题)

反悔贪心=>将“反悔”融入决策集合中(例题)

邻项交换法

括号序列建树(例题)

\(01\) 分讨

静态图(或者其他什么东西)跑倍增(例题)

边拆成起点情况和终点情况(例题)

\(n\) 个数填入 \(n\) 个点=>考虑二分图/网络流(例题)

染色"只染一次"(例题)

两数模 \(m\) 的一种比较思路:

钦定 \(c=a-b\) ,则 \(a \mod m < b \mod m\) 的充要条件为 $ b \mod m + c \mod m>=m $ ,证明手玩一下即可

此时有 \(a/m=b/m+c/m+1\)
=> $ [ a \mod m < b \mod m ] = a/m-b/m-(a-b)/m $
(均为向下取整)

下取整的一种处理:\(\left \lfloor {x/i} \right \rfloor = |S|\),元素 \(k\)\(S\) 中当且仅当 $ k\le x \wedge i|k$ (某次模拟赛)

单个式子某一项有减号且不好处理,考虑拆成多个式子分别算和最后大式子之间相减(同上)

区间 \(LCA\) 等价于区间每个相邻数取 \(LCA\)\(min\)(NOIP2024 T4)

区间内 \(\le k \ge k\) 的数的个数一般的考虑是上主席树,然而在询问支持离线/询问的 \(k\) 就是序列中的数的时候也可以上线段树,把区间内的数从小到大放进去就行(\(P14140\)

处理区间 \([l,r]\) 转化为处理两个前缀/两个后缀(典型应用:数位 \(DP\) ,某些线段树二分)(\(P14140\)

边界不更新其他状态也要继承之前的状态(e.g. \(f_{i,j}=max(f_{i-1,j},f_{i-1,j+1}+...)\)\(j\) 取到最大值的时候不会有后面的更新,但是循环还是要遍历一下 \(j\) 取最大值)(\(abc400g\)

期望题,元素之间没有差别=>只处理一种元素,最后乘元素数量(\(CF464D\)

概率期望都知道要倒着推,但是正难则反的考虑应该是普遍的,其他 \(DP\) 中从 \(n\)\(1\) 推,或者状态设计已经用了/还剩下的互相转换;包括更多方面,限制某决策从某时刻禁止=>时光倒流变成某决策从某时刻解除限制,图论中删边和加边的转换等都是这一思路的运用

浮点数可以在精度范围内胡搞(\(CF464D\)\(10.12\) 核桃周赛 \(T4\)

能转成从 \(1\)\(n\) 的就不写从 \(n\)\(1\) ,这样思维更加符合人类

写出来线段树外面的二分,二分的时候还有线段树操作,那就尽量融线段树上写线段树二分,可以省一只 \(log\)

绝对值拆掉,两种情况分讨,分别做

按位置枚举 <=> 按大小枚举

一个方程中,可以一部分把一个单点钦定出来,一部分把其融进去(\(ABC217F\)

小范围内处理 \([1,n]\) 每个数的因数,可以枚举可能的因数做到 \(nlogn\) 而不是一个一个找做成根号

考虑一下特殊性质有什么用,某些题目的特殊性质具有很强的提示性(\(NOIP2023 T3\)

看似无法优化的 \(DP\) 方程可以放到网格之类的东西上,刻画转移的本质然后变成其他神秘做法(同样 \(NOIP2023 T3\)

数据变化有下界(如 \(x\)->\(max(0,x-i)\) 这种长相),考虑维护最多减少到某值和在此之后加到某值(例题)

存在量词=>全称量词

奇偶一个好做一个不好做考虑把不好做的转成好做的

区修单查<=>单修区查

构造区间,对于某些情况有区间越长越好=>各个区间之间均有交,此外考虑区间错开是否严格不优/不劣于区间包含

仅仅关心相对值(和差之类的),可以对着这一点优化

某元素超过元素总和的一半=>某元素大于其他元素的总和

想到可以二分了,进一步想想能不能直接上单调队列

一些注意事项:

考场上建议自己手写一遍题意,过一遍手可以避免眼睛看到的和脑子里面想的不是同一个东西

think TWICE,code ONCE

注意对思路的“重启”,不管是在考场上还是平时的练习,题做不动了,想的时间太久了,(如超过 \(15min\) )无法清晰解释自己的思路了,重启(先写其他的题/上厕所,这一过程中一定不要再去死磕自己原来丑陋的思路,转移注意力,随后再从头再想一遍,从读题开始来一遍,从选用 \(DP\) 数学数据结构哪个大板块实现开始做一遍)

随时清楚自己在写什么,写出来的东西干了些什么,到底想实现什么

修改一处地方连同构一起改

提交之前编译一遍,最好在 \(linux\) 环境下

复习的时候要重新过一遍整个思路过程,弄明白哪些思路是有前途的而哪些没有,避免反复走上相同的错误/不可做思路

口胡的结论起码要能玩过所有样例再去实现代码,当口胡复杂度显著优于理论上正解复杂度的时候最好多想想是否胡假了,同时要拥有造一些可手玩的样例的能力

刻画操作/实现代码时如果要人为加某个限制,先想一想限制是否真的有必要

枚举子集有 \(O(3^n)\) 方法

数学式子项数较多的时候一定要写清楚每一项的意义

化式子变量常量分离

修改和查询放一起输出的时候要考虑答案为 \(0\) 导致查询误判为修改输不出来的情况

尝试把思考过的正确但不全面的做法拼起来

对边界的分析与特判(\(n==0\),\(n==1\),\(n==m\),\(etc\)

直接交换两个数组如果长度不同要记得把存长度的变量一起换了

二分的下界可能是 \(0\) 也可能是 \(1\) ,上界一倍两倍什么的也都有可能

有数据范围没看到给,多审一下题面找信息(除非题目来源特别史)

把困难写出来,一个个找解决方案

不要只写一个 \(op=getchar()\),可能可以通过样例,但是因为一些神秘原因是可能挂的

删除所有调试代码,不仅包括容易检查的输出,也包括不易察觉的 \(for(i,1,n)\) 等无意义但是耗时的神秘玩意

同一道题尽量统一从 \(0\) 开始或从 \(1\) 开始

\(eps\) 开小一点,比如开到 \(1e-10\)

一些代码上的点:

(在 \(linux\) 环境下编译一遍可以规避以下的大部分错误)

考场上不要用 \(cerr\)

万能头的斜杠不要反了,\(windows\) 下反了也能过编

不要 \(abs(int128)\),事实上用了 \(int128\) 之后最好手写实现简单的函数

字符和整数混合输入,要么关闭输入输出流然后写 \(cin,cout\),要么写:

while(...) op=getchar();

一些模型的实现细节:

点分治记得套上存储点的数组

点分治下传 \(solve(rt)\) 不能写成 \(v\) 或者什么奇奇怪怪的脏东西

点分治等需要去重的东西,如果待选集合不大,考虑一种先尝试更新答案再加入待选集合的思路

树套树(以下默认树状数组套权值线段树)用了离散化后数组规模要开 \(n+m\) 而不是 \(n\) ,线段树空间开双 \(log\) (我好像曾经胡过一嘴空间单\(log\),那是假的)

树套树下传左右的节点集合要确认往那边走再决定传左儿子还是右儿子

线段树下传要记得传懒标记,尤其是维护元素较多的时候更要记得

并查集一定检查合并的两个点是否在同一集合

分块的询问并不都需要重构块,尤其是当重构块的复杂度并非线性的时候更应当三思

欧拉序 \(LCA\) \(ST\) 表的空间也是 \(2\)

一些好用的技巧:

重载运算符:

struct node
{
	int ...;
	node operator +(const node &x)const
	{
		...
		//+号左边是 $*this$ ,但是可以直接用变量名,与重载小于号类似;右边是 $x$
		//例子见 $P5889$
	}
};

线段树中如果只取其中一项的值,需要注意另一项的 \(l,r\) 可能也要返回

自定义排序关键字:

sort(f+1,f+n+1,[&](node x,node y)
	{
		if(x.a==y.a)	return x.id<y.id;
		return x.a<y.a;
	});
posted @ 2025-10-15 18:02  zlc1082  阅读(19)  评论(0)    收藏  举报