一些技巧 && 常数优化 && 出现の错误 [绝赞更新中!]
开坑原因
7.21
今天DTZ大爷教了我一个算欧拉函数的好方法......是质因数复杂度的
这让我想到,这些小技巧小idea,很多时候,可能就是考场上最致命、最一击必杀的“大招”
因此开个坑记录一下,定有好处
7.21
欧拉函数的意义是比一个数小的数中有多少个和它互质的,不要考场上想到了这句话想不到欧拉函数
然后是求欧拉函数的一个方法
设一个数$x=\prod_{i=1}{k}p_i$,那么:
$\varphi(x)=\prod_{i=1}{k}(p_i-1)p_i=x\prod_{i=1}^{k}\frac{p_i-1}{p_i}$
7.24
在做FFT,NTT之类的题目时,会用到大量的模数
这时,以下三种方法:
#define MOD 1000000007
const ll MOD=1000000007
ll MOD=1000000007
第一种快于第二种快于第三种
而且都是快很多的那种快法
因此最好使用第一种
7.25
NTT中,做多项式求逆和多项式开根的时候,每次迭代只需要取前len项出来,然后len到(len<<1)的项一定要清零
这样会快很多
同时注意原式中能约的就约掉,也能提升常数
7.29
$\varphi(i\ast j)=\frac{\varphi(i)\varphi(j)d}{\varphi(d)}$
其中$d=gcd(i,j)$
莫比乌斯函数的性质利用
$\mu\ast I = \epsilon$
$[gcd(i,j)==1]=\sum_{e|i,e|j}\mu(e)$
这玩意有啥用呢?比如说我要求$\sum_{i=1}n\sum_{j=1}m\varphi(ij)$
那么可以这么化式子
原式
$=\sum_{d=1}^n \frac{d}{\varphi(d)} \sum_{i=1}^n \sum_{j=1}^m \varphi(i)\varphi(j) [gcd(i,j)==d]$
$=\sum_{d=1}^n \frac{d}{\varphi(d)} \sum_{i=1}^{\frac{n}{d}} \sum_{j=1}^{\frac{m}{d}} \varphi(id)\varphi(jd) [gcd(i,j)==1]$
$=\sum_{d=1}^n \frac{d}{\varphi(d)} \sum_{i=1}^{\frac{n}{d}} \sum_{j=1}^{\frac{m}{d}} \varphi(id)\varphi(jd) \sum_{e|i,e|j}\mu(e)$
$=\sum_{e=1}n\mu(e)\sum_{d=1}\frac ne\frac d{\varphi(d)}\sum_{i=1}^\frac n{de}\sum_{j=1}^\frac m{de}\varphi(ide)\varphi(jde)$
设$T=de$
那么原式
$=\sum_{T=1}^n \sum_{d|T} \mu(\frac{T}{d})\frac{d}{\varphi(d)} \sum_{i=1}^{\frac{n}{T}} \varphi(iT) \sum_{j=1}^{\frac{m}{T}} \varphi(jT)$
这样题目就变简单了
7.30
今天又做到关于树、堆之类的东西的形态构建题目了
对于问你一棵二叉树/多叉树有几种构建方式的,可以考虑从每个节点的子树的角度去DP、设方程,然后用多项式优化,或者组合数之类的
8.2
设$F_i$表示斐波那契数列的第$i$项,那么:
$gcd(F_i,F_j)=F_{gcd(i,j)}$
同时注意线性筛中间要break的是$i$ $mod$ $ pri[j] 0$,不要漏掉了$0$!!!
积性函数的判定:
两个积性函数的狄利克雷卷积仍然是积性函数
8.4
二项式反演:
$F(n)=\sum_{i=0}^n C_n^i G(i)$
$G(n)=\sum_{i=0}^n (-1)^{n-i} C_n^i F(i)$
8.12
$LCT$的$splay$之前写的$push$中有的时候无法使用递归写法,此时要注意弹栈过程中的$top--$
while(sta[top--]) pushdown(sta[top]);
while(sta[top]) pushdown(sta[top--]);
下面的是对的,上面是错的
8.13
$SAM$的常用操作是把$fail$指针(也就是$fa$)反过来,然后在树上$dp$(这个好像很sb的样子我为什么要写上来qwq)(我太菜了)
由$Polya$定理可以计算把一个长度为$n$的环涂上$m$种颜色的不同方案:
$L=\frac{1}{n}\sum_{i=1}^{n} m^{gcd(i,n)}$
9.10
好久没更新了......
长链剖分+单调队列合并,可以把求树上长度为$[L,R]$区间的路径的相关问题做到$O(n)$
遇到长得像二次方程根的那种递推、通项之类的东西,可以考虑反推特征根方程
两棵树通过一条边连在一起的时候,新树的直径端点是原来两棵树的四个端点中的两个
遇到和深度相关的、有继承关系的问题,可以考虑同一条链共用dp值的方式
SA遇到处理原序列顺序的相关问题时,可以考虑加入主席树,按照sa顺序加入,元素是原位置
10.25
一个多月没更新......
树形dp在n小的时候,可以考虑以每个点为根进行dp,这样可以加入一些限制,可能有奇效
树状数组可以维护区间加、区间查询和!(详见HNOI2017影魔)
树的拓扑序个数为$\frac{n}{\prod size(u)}$
1.5
诈尸式更新
考虑一个函数是否为多项式时,可以差分它
如果经过了$k$次差分后得到0,那么它是一个$k-1$次多项式
这个可以和拉格朗日插值一起用
4.12
泰勒展开.....
看到和式有着$\sum_i delta\ast\frac{xi}{i!}$的形式的时候,要考虑到$ex$的泰勒展开式:
$ex=\sum_{i=0} \frac{x^i}{i!}$
4.14
更新一个非常规思路list
纯序列问题:cdq分治,整体二分,树套树,奇怪的线段树
序列问题且只和区间边界有关:先考虑dp,不行可能是线段树(usaco式合并)
需要维护区间对一个值取max/min:吉老师线段树(Segment Tree Beats!)
计算几何奇怪形状:分步枚举,考虑哪些元素的确定会对其他人限制最大
关于模意义下二次方程:二次剩余
序列上的点是连续的情况(也就是本来要用微积分的):注意此时序列上任选两个点重合概率为0
待续(可能后面会考虑把这个东西改成一个trick列表.....?)
5.3
期中考试去了......有一段时间没做题
还好考了个年25,还看得过去吧(虽然自己不是特别满意)
= =
遇到排序相关、交换相关的题目,可以考虑按照元素大小变成零一序列,可能有奇效
5.4
四色定理类似问题可以先生成树,再看剩下的边是不是二分图,最后两个分别染色然后合并
除此之外就只能爆搜了
注意这种条件下不满足四色定理的图一定有奇环:二分图判定原理
考虑dp的时候,要注意一些全局的限制:可能会遇到dp的两个维度有乘起来不超过一个值的情况
此时可能可以导出调和级数复杂度!
走路+选择路上元素问题的dp,可以反过来考虑,不是dp已经选了那些,而是dp剩下的都没选的时候(也就是走到哪里为止)可以配合上述调和级数做
这种dp要注意的是,关于走路中的一些“体力限制”,会出现你没走到哪里可能会花更少的“全局体力”,此时注意在dp中考虑这一因素的影响
调和级数dp在滚动数组的时候采用一个一个重置为in的方式比较可靠,不然很可能memset复杂度挂
5.7
如果想对于一个n点图的凸包求出去掉凸包上每一个点后,在新的n-1点图中得到的新凸包的点集的并集,可以采用这样的方法:
设原凸包点集依次为$a[1...m]$,那么对于奇数下标的标上颜色一,偶数颜色二,如果$m$是奇数那最后一个标颜色三、第一个去掉颜色
然后做三次求凸包,每次去掉一种颜色的点(没有颜色的就不管),三个凸包上所有的点集合就是所求的并集
这个方法简而言之就是每隔一个点去掉一个,可以把这一算法复杂度从$O(n^2\log n)$降到$O(n\log n)$
排列问题双巨头:括号序列!线段树!
5.8
线段树里面不仅可以套凸包优化决策,居然还可以套半平面交......
遇到区间交集题目或者什么别的东西,有“选择的长度和贡献线性相关”的,可以考虑一下从一次函数的观点看问题,可能能变成几何题
遇到不会dp,如果n3或者kn2能接受的话,想一想区间dp的方法,并尝试一波四边形优化
四边形优化不一定要证明,可以打个表试一试(当然前提是要先确保原来的区间dp是对的,要先对拍再打表)
5.9
线段树求最小值和最小值个数可以解决区间覆盖型问题
5.12
多模式串匹配算法要想到AC自动机!可以在上面跑dp
注意AC自动机要合并fail树上所有祖先节点的信息
平均数求和问题如果有二分性则可以01分数规划!
平均的那个除N挪到右边,再挪回来,可以去掉siz在dp中的限制
5.13
cf559div1打的奇差无比......找规律还能fst,策略大失败,怀疑自己的智商没资格搞OI了
遇到
有一个排列,给出这个排列每个位置的一个和后面位置以及大小有关的信息(比如在它后面第一个比他大的),求这个排列
的这种题,可以考虑排列的合法性。很多时候会发现会出现例如$i<j<p[i]$则$a[i]>a[j]$必须满足的情况(这个基于区间大小限制)
这样就可以建立限制拓扑图,可以拓扑排序赋值
5.16
对于一些有很多位置,每个位置有很多取值,然后问你所有这些取值的前$k$大的问题,可以使用优先队列完成:
用pair记录取值和取值位置,然后每次取出优先队列里面取值最大的那个,然后在对应的位置查询第二大(第三大、第四大……)的取值,再插入
适用于可以查询区间$k$大的数据结构,例如主席树、可持久化trie等
sam有一些新get的技巧,去看我写的sam那篇博客吧
8.2
博弈图没有环
有环就不要往博弈上面想。这种题cf和ACM会有
有环的话说明这个选手就不会输了!