SDSC笔记
Day1
图论杂讲
联合权值:枚举中转点 \(\mathcal{O}(n)\)。
关押罪犯: \(X\) 为自己, \(X'\) 为对面,按照怒气值排序,每次把 \(X\) 和 \(Y`\) 以及 \(Y\) 和 \(X`\)` 合并,出现冲突就退出。
食物链: 类似关押罪犯,\(X_1\) 为自己,\(X_2\) 为食物,\(X_3\) 为天敌。
车站分级: 每辆车会给车站带来一个大小关系,把未停靠向已停靠的车站连边,拓扑排序的时候dp,暴力连边 \(O(n^2m)\) ,引入辅助点时间复杂度 \(O(nm)\)
BZOJ 2563: 把边权分到两个点权上
运输计划: 二分最大值,剩下不满足条件的边用树上差分来记录边有多少路径,每条为 \(k\) 条路径经过的边枚举一下删哪条边。
CF1349C:\(c_{i,j}\) 为这个时刻进入大小大于 \(1\) 的连通块,每个连通块向外扩展大小为 \(1\) 的连通块
CF209C: \(k\) 个连通块用 \(k-1\) 条边连起来,选度数为奇数的点相连,特判整个是连通图,如果连通块里没有奇点就浪费一条边连。
CF1311E: 构造出完全二叉树,每次把点扔到最长的一个链上。
华容道: \(f(i,j,k)\) 表示棋子位于 \((i,j)\) ,空格位于四周哪个位置,预处理状态之间的转移,让空格bfs到另外三个点,连边,直接和空格交换连边,跑bfs,复杂度 \(\mathcal{O}(n^2m^2+qnm\log(nm))\)。
CF875F:一个公主看做一条边,答案形成若干个基环树,求整张图的最大生成环套树,kruscal,给并查集加一个标记,对于每条边,看是树还是基环树,连边即可。
BZOJ 2238:如果边不在最小生成树上,答案无影响。如果是树边,等同于求跨过这个树边的非树边最小边权值。边权从小到大排序,每次把未被标记的点打上标记,并查集维护某个点上方第一个未被标记的点。
HDU 5215: 判断奇环就是判断是否为二分图,判断偶环:建出dfs序树后,如果两个点之间有返祖边并且深度之差为奇数就是偶环,深度之差为偶数就是奇环,如果两个奇环相交则可以形成一个偶环(删掉相交部分)。判断相交可以暴力打标记,因为每条边最多遍历到一次。
ICPC2018 青岛站 F:
有 \(n\) 个人,进行 \(k\)轮决斗,每一场决斗两两匹配,对于两个人比赛中最多决斗一次。若存在四个人 \(a,b,c,d\),\(a\) 和 \(b\) 在第 \(i\) 轮决斗,\(c\) 和 \(d\) 在第 \(i\) 轮决斗,\(a\) 和 \(c\) 在第 \(j\) 轮决斗,则 \(b\) 和 \(d\) 必须也在第 \(j\) 轮决斗。
构造一组方案,无解输出 Impossible。
\(k\) 可行则 \(k-1\) 也可行,相当于给定 \(n\) ,问最多决斗多少轮。k为二进制n最后几个0,\(2^k-1\)轮。
CF1335F: 内向基环树
CF1344C
CFGtm 100269K
Makoto SOejima's Contest 4
CF1340D
Day2:
线段树:
维护数列,区间赋值,区间求和,区间做按位与: 每一位的答案都是独立的,所以给每个二进制位开一棵线段树,区间推平/求和即可。做法类似我之前写的一篇博客的Part3部分
维护区间数的种数(离线)(HH的项链):区间 \(r\) 排序,对于每个 \(r\) ,\(v_r=1,v_{pre_r}=0\) 对于每个 \(l\) 区间求和即可。
\(n\) 个正数和 \(m\) 个区间,要求选出恰好 \(k\) 个区间,交集内数字和最大
二维数点: 可以利用差分变成询问下界为 \(0\) 的矩形,每次 y++
相当于把小于等于一个 \(y\) 的点拍到x轴上,询问下界为 \(0\) 的矩形就变成了询问区间和。
\(n\) 个球排成一列,每个球有一个颜色,每种颜色有一个价值,选定一个区间,使得所有在这个区间中出现恰好一次的颜色的价值之和,范围1e5:
\(pre_x\) 为颜色上一次出现,\(next_x\) 为下一次。则 \(pre_x<l\leq x,x\leq r <next_x\),则可以看成 二维平面上 \(pre_x\) 到 \(x\),\(x\) 到 \(next_x\) 的矩形值加上一个值。就变成若干矩形加求一个点的最大值,扫描线即可。
多组询问序列中的区间MEX: 对于 \(x\) (所有的 \(x\) ,并不是非在 \(a\) 中出现)出现的每个位置,则 \(pre_l\leq r \leq x\) 的区间要考虑答案是否为 \(x\) ,取 \(\min\) ,变成矩阵上扫描线,每次拍点最小值。
李超树: 平面直角坐标系,每次加入一条直线,求交点。
区间开根,区间求和: 一个数 \(x\) 最多只会被开 \(\log\log x\) 次,只需要维护区间最大值,看是否为1,不是就暴力开,如果是1就没必要再开,直接退出即可。
区间取模,区间求和: 一个数 \(x\) 变成 \(x\bmod p\) 是严格小于 \(\frac{x}{2}\) 的,所以最多只会被开 \(\log x\) 次,同上暴力即可。
主席树(可持久化线段树)
扫描线强制在线: 用主席树维护,每次拍一个点建立一棵新版本线段树,每次询问前缀区间相当于在历史版本上进行区间查询。
静态区间第 \(k\) 小: 可持久化值域线段树(线段树维护桶),每次令 \(b[a[i]]+1\),形成一个新的版本,(线段树维护 \(b\) ),求第 \(k\) 小每次询问区间的二分后的值的排名,根据和 \(k\) 比较的结果向下递归。
\(n\) 个帽子,一个帽子下有球。\(m\) 个操作序列,每个操作形如交换两个帽子。多组询问 \(l,r,x\) ,表示一开始球放进 \(x\) 个帽子里,执行 \(l\) 到 \(r\) 到操作后球在哪里。\(a_i\) 表示经过 \([l,r]\) 区间后 \(i\) 到哪儿,\(b_i\) 为 \(i\) 在 \([1,l]\) 区间交换前的位置。主席树把 \(a,b\) 可持久化,查询 \(a[b[i]]\)
线段树优化建图
线段树分治
Day3
网络流三种最基本的类型为最大流、费用流、最小割。
网络流的难点在于建模,建模后上模板就可以求解。
抽象模型: 流水管道模型
源点(\(S\))和汇点(\(T\)),有向图,每个节点之间有个管道有容量,从 \(S\) 出发释放水,传到 \(T\) 。
最大流
最大流即为从 \(S\) 到 \(T\) 最大能流到多少水。
定义: 网络: 有向图 \((V,E)\) ,指定源点 \(S\) 和汇点 \(T\),每条边给定容量 \(c\)。
边的流量,每条边的流量变量f满足 \(0\leq f \leq c\)
流量平衡: 除 \(S,T\) 外,点流入的流量等于流出的流量。
网络的流量: \(S\) 流出的流量也等于 \(T\) 流入的流量。
求最大流:
建反向边,流量为正向边流量的相反数,流水的时候每次选一条没有流满的路径,尽量将其流满,找不到这样的路径为止。
Dinic:
只要网络中还有通路,就按到 \(S\) 的距离分层,在保证流量只从第 \(i\) 层流向 \(i+1\) 层的前提下(变成一个拓扑图),尽可能增加流量。
理论最差复杂度 \(\mathcal{O}(n^2m)\)
Dinic做二分图匹配的复杂度为 \(\mathcal{O}(n^{0.5}m)\)
二分图最大匹配(网络流):
建立一个源点 \(S\) 连向一侧所有点,另一侧所有点连向 \(T\) ,\(S\) 到 \(T\) 的最大流即为最大匹配。(容量都为 \(1\) )
飞行员配对方案: 二分图最大匹配模板
POJ3281 Dining 保证牛只被匹配一次,拆一下点: S->食物->牛1->牛2->饮料
假期的宿舍: 每个床看做一个点,每个人看做一个点,题目即为人和床的二分图匹配,最大流看是不是所有人都能匹配到床
星际战争: 二分答案 \(t\) ,源点流向武器 \(b_i*t\),武器流向机器人 \(inf\),机器人流向汇点 \(a_i\) ,判断最大流是否为 \(\sum a_i\) 即可。
紧急疏散: 二分答案 \(k\) ,TLE想法: 分层图,每个相邻空地向下一次连一条 \(inf\) 边,每个时刻的门都向汇点连一条 \(1\) 边,源点向第一层空地连 \(1\) 边,空地向相邻门连一条 \(1\) 边。正解: 对于每个门都会产生 \(k\) 个出门的机会,求出每个人到每扇门的距离后,即可知道每个人能选择哪些机会,二分图匹配判断是否每个人能分配到一个机会。
考虑优化: 每个门向下一个时刻连 \(inf\) 边,每个人向他能拿到的第一个机会连边。
费用流:
给定一个网络,给每条边一个费用 \(w\) ,若流量为 \(f\) ,则需要费用 \(w*f\) 。
最小/大费用流
最小/大费用最大流
费用流做法: 按费用找一条 \(S\) 到 \(T\) 的最短通路,将这条路径尽量跑满,如此重复。反向边的费用为该边费用的相反数。
分配问题: 二分图最大权值,最大/小费用最大流即可。
网络扩容: 第一问最大流模板,第二问边连费用0流量c,再连费用k容量inf最小费用最大流。
订货: 源点(进货) 向每个月连容量 \(inf\) 费用 \(d_i\) ,每个月向下一个月连容量 \(S\) 费用 \(m\) ,每个月向汇点(卖货)连容量 \(U_i\) ,费用 \(0\) ,跑最小费用最大流。
球队收益: 有几场比赛就连几条边,其中费用是剩余 \(i\) 场时支持的差值,是递增的,所以一定是选前几条边。
最小割
给定一个网络,删掉一条边的代价就是这条边的容量,要求删掉一些边使得 \(S\) 与 \(t\) 不连通,求最小代价。
定理: 在数值上最小割=最大流。
狼和羊的故事: 所有羊看做一个源点(超级源点流向所有羊无穷),所有狼也是看做一个汇点(流向超级汇点无穷),能到达的点之间连边,流量1,跑最小割。
善意的投票:S和T代表睡觉和不睡觉,好朋友之间连1的边,小朋友向自己的主见连1的边。
能量魔方
Day4
单调数据结构优化
\(f_i=\min^{x-1}_{k=b[x]}\{g[x]\}+w[x]\)
满足 \(j\leq k\) 并且 \(g_k\leq g_j\) 则 \(j\) 毫无用处了,所以只需要单调队列优化达到均摊 \(\mathcal{O}(n)\)
多重背包:
\(f[i]=\min\limits_{i=0}^{c[k]}\{f[x-i\cdot w[k]]+i\cdot v[k]\}\)
这个转移很麻烦,因为状态都不是连续的,考虑到一个状态能转移到的状态下标模 \(w[k]\) 都相同,那么在模 \(w[k]\) 相同的状态内,决策区间是连续的。
设 \(h(x,y)=f[x\cdot w[k]+y]\)
那么
\(h(x,y)=\min\limits_{i=x-c[k]}^{c[k]}\{h(i,y)+(x-i)\cdot v[k]\}\)
为什么呢?换成之前的把 \(h\) 替换成 \(f\) 就很显然了。
\(f[x\cdot w[k]+y]=\min\limits_{i=x-c[k]}^{c[k]}\{f[i\cdot w[k]+y]+(x-i)\cdot v[k]\}\)
其中 \(x-c[k]\) 在 \(c[k]\) 不变的情况下单调不降,可以转化成前面的模型。其时间复杂度为 \(\mathcal{O}(nm)\)
Luogu P3572 Little Bird
\(f[i]=\min\limits_{j=i-k}^i f[j]+[a[j]<a[i]]\)
\(i<j\) 且$ fi>fj$ 并且 \(a_i<a_j\) 显然 \(i\) 不可能比 \(j\) 更优,就弹出单调队列,于是以 \(f\) 为第一关键字,\(a\) 为第二关键字,单调队列维护即可。
SCOI2020 股票交易
\(f[i][j]\) 第 \(i\) 天有 \(j\) 股股票。
\(f_i=\max:\)
\(f[i-1][j]\)
\(f[i-W-1][k]-a_i*(j-k),max\{0,j-c_i\}\leq k \leq j\)
\(f[i-W-1][k]+b_i*(k-j),j\leq k \leq \min{K,j+d_i}\)
后两个式子单调队列优化。
化简一下:
\(f[i-W-1][k]-a_i*j+a_i*k\),对 \(f[i-W-1][k]+a_i*k\) 为关键字单调队列优化。
\(f[i-W-1][k]+b_i*k-b_i*j\),对 \(f[i-W-1][k]+b_i*k\) 为关键字单调队列。
斜率优化:
HNOI2008 玩具装箱:
设 \(f_j\) 表示前 \(i\) 个玩具,装在任意多个容器花费的最小费用,枚举上一个分组的分界点,可得:
\(f[i]=\min\limits_{j=0}^{i-1}\{f[j]+(sum[i]-sum[j]+i-j-1-L)^2\}\)
设 \(s_i=sum[i]+i,L'=L+1\)
\(f[i]=f[j]+(s_i-s_j-L')^2\)
\(f[j]+(s_j+L')^2=f[i]-{s_i}^2+2*s_i*(s_j+L')\)
设 \(y_j=f[j]+(s_j+L')^2,x_j=2*(s_j+L'),k_i=s_i,b_i=f[i]-{s_i}^2\)
上式变成了
\(y_i=k_ix_j+b_i\)
过 \((x_i,y_i)\) 且斜率 \(k_i\) 的直线,选择合适的 \(x_i,y_i\) 求最小截距。
把 \((x_i,y_i)\) 滑到平面直角坐标系上(黑点),搞出下凸包,用斜率为 \(k_i\) 的直线向上平移,直到经过一个黑点,此时的截距就是最小截距。
相邻黑点的斜率 \(k_i\) 是递增的,每加进去一个点,用单调队列维护下凸包。
每条直线的 \(k_i,x_i\) 是上升的,所以单调队列下凸包上的点。
(维护线段斜率的过程)
JSOI2011 柠檬:
性质:分的每一段的首尾元素一定相同,且为选出的元素。
证明: 如果某一段不选首尾位置的元素,那么把首尾元素的位置划到别的短或者新开一段答案肯定不会差
\(f[i]=\max\limits_{1\leq j\leq i,a_j=a_i}\{f[j-1]+a_i*(s_[i]-s[j]+1)^2\}\)
化简后得
\(f[j-1]+a_i(s[i]-1)^2=f[i]-a_i{s_i}^2+2a_is_i(s[j]-1)\)
因为转移的必要条件为 \(a_i=a_j\),所以 \(a_i\) 看成常数即可。
所以 \(y_j=f[j-1]+a_i(s[i]-1)^2,x_j=2a_i(s[j]-1),k_j=s_i,b_i=f[i]-a_i{s_i}^2\)
转化成了 \(y_j=k_ix_j+b_i\)
要求的是截距最大值,要维护上凸包,斜率 \(x_j\) 对于每个 \(a_i\) 是单调递增的,所以是从前往后取,取在上凸包最后的点,用单调栈维护 \(\mathcal{O}(n)\) 。
四边形不等式
\(f(l,r)=\min\limits_{k=l}^{r-1}\{f(l,k)+f(k+1,r)\}+w(l,r)\)
直接转移 \(O(n^3)\) ,当 \(w(l,r)\) 满足某些性质时可以优化。
-
区间包含单调性: \(l\leq l' \leq r' \leq r\)
-
四边形不等式: \(l_1\leq l_2 \leq r_1 \leq r_2\) 均有 \(w(l_1,r_1)+w(l_2,r_2)\leq w(l_1,r_2)+w(l_2,r_1)\)
性质: 若 \(w(l,r)\) 包含单调性和四边形不等式,则 \(f(l,r)\) 也满足四边形不等式。
定理1: 若 \(f(l,r)\) 满足四边形不等式,设 \(m_{l,r}\) 为最优决策点下标,则有 \(m_{l,r-1}\leq m_{l,r}\leq m_{l+1,r}\)
所以在计算 \(f(l,r)\) 的同时将其最优决策点 \(m_{l,r}\) 记录下来,每次转移枚举 \([m_{l,r-1},m_{l+1,r}]\) 内的决策点即可。
枚举次数为 \(\sum\limits_{l=1}^{n-1}\sum\limits_{r=l+1}^{n}(m_{l+1,r}-m_{l,r-1})=\sum\limits_{i=1}^n(m_{i,n}-m_{1,i})\leq n^2\)
石子合并:
\(f(l,r)=\min\limits_{k=l}^{r-1}\{f(l,k)+f(k+1,r)\}+s(l,r)\)
\(s(l,r)\) 为 \([l,r]\) 内石子之和。它满足区间包含单调性,四边形不等式。
另一种四边形不等式优化:决策单调性优化:
\(f(r)=\min\limits_{l=1}^{r-1}\{f(l)+w(l,r)\}\)
\(w(l,r)\) 满足四边形不等式时可以优化。
定理: 若 \(w(l,r)\) 满足四边形不等式,对于 \(r_1\leq r_2\) 设 \(k_1,k2\) 为 \(f(r1)\) 和 \(f(r2)\) 的最优决策点,则有 \(k1\leq k2\) 。
使用分治的思想,知道了 \(mid\) 的决策点 \(k_{mid}\) ,根据决策单调性,对于所有的 \(x<mid\) ,\(f(x)\) 的决策点一定 \(\leq k_{mid}\) 反之一定 \(\geq k_{mid}\)。所以采用分治的思想,记录每个区间的决策点的上下界。可以在 \(\mathcal{O}(n\log n)\) 的复杂度解决问题,即为决策单调性优化。
POI2011 Lightning Conductor & JSOI2016 灯塔
\(p_i=\max\limits_{j=1}^{i-1}\{h_j-h_i+\sqrt{|i-j|}\}=-\min\limits_{j=1}^{i-1}\{-h_j+h_i-\sqrt{|i-j|}\}\)
\(w(l,r)=\sqrt{|i-j|}\)
\(w(l,r)\) 满足四边形不等式。
ZJOI2010 基站选址
\(f[i][j]\) 为第 \(i\) 个放基站,前 \(i\) 个村子共放了 \(j\) 个基站,枚举上一个放基站的位置 \(k\) ,则dp方程为
\(f[i][j]=\min\limits_{k=0}^{i-1}\{f[k][j-1]+c_i+cost(k,i)\}\)
\(cost(k,i)\) 表示在 \(k\) 和 \(i\) 放基站且中间不放基站的情况下 ,\([k,i]\) 之内的所有村子赔偿费之和。
对于每个村庄,预处理出 \(l[x],r[x]\) 表示能够覆盖到 \(x\) 这个村庄的最左端与最右端基站的位置。那么此村庄会对 \(cost(a,b)\) 产生贡献当且仅当 \(l[x]>a\) 且 \(r[x]<b\)
从小到大枚举 \(j\) ,从 \(f[*][j-1]\) 更新到 \(f[*][j]\) 。
从小到大枚举 \(i\),使用线段树维护 \(f[*][j-1]+cost(*,i)\) ,初始时,线段树上每个位置为 \(f[*][j-1]\)。
更新 \(f[i][j]\) 时,先从线段树 \([1,i-1]\) 查询最小值再加上 \(c_i\) 作为 \(f[i][j]\),对于所有的 \(r[x]=i\) 的 \(x\) 在线段树上对区间 \([1,l[x]-1]\) 进行区间加 \(w_i\),之后枚举下一个 \(i\) 。由于每个 \(x\) 至多被枚举到一次,所以对于每一个 \(j\) 线段树的操作是 \(O(n)\) 级别的。
时间复杂度 \(\mathcal{O}(nK\log n)\)
Day5
扩展欧几里得
求 \(ax+by=gcd(a,b)\) 的一组正整数解。
欧几里得定理: \(gcd(a,b)=gcd(b,a\bmod b)\)
假设已经知道了 \(bx'+(a \bmod b)y'=gcd(a,b)\) 的一组正整数解。
将其与 \(ax+by=gcd(a,b)\) 联立,得
\(ax+by=bx'+(a-\lfloor\frac{a}{b}\rfloor b)y'\)
\(=bx'+ay'-\lfloor\frac{a}{b}\rfloor by'\)
\(=ay'+b(x'-\lfloor\frac{a}{b}\rfloor y')\)
所以不断往下递归,直到 \(b=0\) 时,可直接解得 \(x=1,y=0\) 。
求乘法逆元:
若存在正整数 \(a,b,p\),满足 \(ab\equiv 1(\bmod p)\),则 \(b\) 是 \(a\) 在 \((\bmod p)\) 意义下的乘法逆元。
以上同余方程可化为 \(ax+py=1\) (\(x\) 即为求得的 \(b\))
根据裴蜀定理,该方程有解的充分必要条件是 \(gcd(a,p)=1\) 即为 \(a,p\) 互质。
时间复杂度 \(\mathcal{O}(\log a)\) 。
当 \(p\) 是质数的时候,有费马小定理 \(a^{p-1}\equiv 1(\bmod p)\),在 \(\mathcal{O}(\log p)\) 复杂度内求出。
中国剩余定理:
\(\begin{cases}x\equiv a_i (\bmod m_1)\\x\equiv a_i (\bmod m_i)\\...\\ x\equiv a_k (\bmod m_k)\end{cases}\)
当题目中的模数不是质数的时候,可以分成质因子分别求解后用中国剩余定理合并。
扩展中国剩余定理:
NOI2018 屠龙勇士
BSGS,离散对数问题
形如 \(a^b \equiv c(\bmod m)\) 的同余式:
-
已知 \(a,b\) 求 \(c\) :快速幂。
-
已知 \(a,c\) 求 \(b\) : 离散对数问题。
-
已知 \(b,c\) 求 \(a\) : 高次剩余问题。
现在讨论离散对数问题。
离散对数问题到现在为止并没有完全解决(因为没有多项式时间复杂度)
BSGS 算法:
主要运用分块的思想,处理 \(a^b\equiv c (\bmod p)\) 中 \(a\) 与 \(p\) 互质的情况。
设 \(b=km+i\),\(m\) 是设定的一个常量,一般取 \(\sqrt{p}\)
此时有 \(a^{km+i}\equiv c(\bmod p)\) 即 \(a^i\equiv c*a^{-km}\)
对于 \(i\in [0,m)\) ,将所有的 \(a^i\) 预处理出来存到一个 map
(Baby Step)
从小到大枚举 \(k\) ,在 map
里面查找是否存在 \(c*a^{-km}\)(Giant Step)
时间复杂度 \(\mathcal{O}(\sqrt{p}\log p)\)
SDOI2011计算器
SDOI2013随机数生成器
原根
欧拉定理: 若 \(a,p\) 互质,则 \(a^{\varphi(p)}\equiv 1 (\bmod p)\)
如果 \(\varphi(p)\) 是 \(a^x\equiv 1 (\bmod p)\) 的最小正整数解,则称 \(a\) 是模 \(p\) 的一个原根。
原根是非常类似于复数单位根,故有一些很好的性质,当 \(p\) 是质数的时候,原根有如下等价定义。
如果 \(g\) 是模 \(p\) 的一个原根,则 \(g^1,g^2,g^3....g^{p-1}\) 在模 \(p\) 意义下两两不一,同时注意到模 \(p\) 剩余系只有 \(0...p-1\) 这 \(p\) 个数,因此 \(g^1,g^2,...g^{p-1}\) 取遍 \(1,2....p-1\) 所有的数。
原根的个数比较多,且最小的原根一般比较小,直接枚举验证即可,枚举次数是常数级别。
对于 \(p\) 比较大时,\(\varphi(p)=p_1,p_2...p_k\),可以相同,对于一个数 \(g\) ,对于所有的....(待补)
高次剩余问题:
求解 \(x^a\equiv b (\bmod p)\)
当 \(p\) 是质数时:
-
若 \(b=0\) ,有 \(x\equiv 0 (\bmod p)\)
-
否则,求出原根 \(g\) ,则原方程变为 \(g^{ax'}\equiv g^{b'} \bmod p\),用BSGS求出 \(b'\) ,之后线性同余方程 \(ax'\equiv b'(\bmod p-1)\),使用exgcd。
数论函数
积性函数: 设 \(f(x)\) 是一个数论函数,若对于任意互质的正整数对 \(a,b\) 均有 \(f(ab)=f(a)*f(b)\) 则 \(f(x)\) 为积性函数。
完全积性函数: 不需要 \(a,b\) 互质的积性函数。
常用的积性函数:
-
常数函数 \(1(x)=1\)
-
元函数: \(\varepsilon(1)=1,\varepsilon(x)=0(x>1)\)
-
单位函数: \(id(x)=x\)
-
幂函数: \(id_k(x)=x^k\)
-
欧拉函数 \(\varphi(x)\) 为小于等于 \(x\) 且与 \(x\) 互质的数的正整数的个数。
-
莫比乌斯函数 \(\mu(x)\)
-
除数函数: \(\varrho_k(x)=\sum_{d|x}d^k\)
欧拉函数
欧拉函数是个积性函数。
欧拉函数取值。
对于质数 \(p\) ,有 \(\varphi(p)=p-1,\varphi(p^{k-1})=p^k-p^{k-1}=p^k(1-\frac{1}{p})\)
由欧拉函数的积性,设 \(n=\prod_{{p_i}^{k_i}}\) 则
\(\varphi(n)=\varphi(\prod_{{p_i}^{k_i}})=\prod\varphi(p_i^{k_i})\)
质因数分解在 \(\mathcal{O}(\sqrt{n})\) 的复杂度内求得一个数的欧拉函数。
欧拉函数可以由线性筛(欧拉筛法)预处理得到。
考虑线性筛的过程: 对于一个数 \(i\) ,从小到大枚举当前筛出的质数 \(p_j\) 筛掉 \(i*p_j\) ,直到 \(p_j|i\) 为止。
假设已经知道了 \(i\) 的欧拉函数值,如果 \(p_j\) 不是 \(i\) 的因子,则由积性。
\(\varphi(i*p_j)=\varphi(i)*(p_j-1)\)
否则 \(\varphi(i*p_j)=\varphi(i)*p_j\)
莫比乌斯函数:
当 \(x=1\) 时,\(\mu(x)=1\)
当 \(x\) 的质因子分解中所有的质数次数是 \(1\) ,则 \(\mu(x)=(-1)^k\),\(k\) 是因子个数。
当 \(x\) 有平方数因数时为 \(0\)。
线性筛莫比乌斯函数。
\(p_j\) 不是 \(i\) 的质数,则 \(\mu(i*p_j)=-mu(i)\),否则, \(i*p_j\) 的质因数分解中 \(p_j\) 的次数一定大于 \(1\) ,则 \(\mu(i*p_j)\) 为 \(0\) 。
除数函数
可以用埃氏筛在 \(O(n\log \log n \log k)\) 的时间复杂度内求出,根据定义算即可。
数论函数的乘积和狄利克雷卷积
利用乘积和狄利克雷卷积来构造新的数论函数。
乘积: \(f(n)g(n)\)
狄利克雷卷积: \((f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d})\)
性质:
·两个积性函数的乘积和狄利克雷卷积仍是积性函数。
·两个完全积性函数的乘积和狄利克雷卷积仍然是完全积性函数。
·乘积和狄利克雷卷积满足交换律和结合律。
重要的卷积:
\(\mu*1=\varepsilon\)
\(\varphi*1=id\)
莫比乌斯反演
欧拉函数另一种表达形式: \(\varphi(n)=\sum_{i=1}^n\varepsilon(gcd(i,n))\)
由 \(\mu*1=\varepsilon\)
有
\(\mu*id=\varphi\)
另一个推论:
有 \(\mu*1=\varepsilon\),同时由定义可得 \(\varepsilon*1=1\)
\(\varphi*1=id\)->\(\mu*id=\varphi\)
\(\varepsilon\)(待补)
莫比乌斯反演定理, \(f,g\) 是两个数论函数,则有
\(f*1=g\)<->\(\mu*g=f\)
对于所有的数论函数 \(f\) ,均有 \(f*\varepsilon=f\),也就是说 \(varepsilon\) 是狄利克雷卷积的单位元。
因为 \(\mu*1=\varepsilon\),所以 \(\mu\) 和 \(1\) 互为逆元。
莫比乌斯反演主要考察:
-
莫比乌斯反演的应用和卷积结论的转换
-
交换求和号
-
数论分块
-
gcd和lcm的转化
Day6
多项式
多项式加减乘法
多项式的除法:
可以证明一定存在唯一的多项式\(q(x),r(x)\) 满足:
\(A(x)=q(x)B(x)+r(x)\)
\(q(x)\) 称为 \(B(x)\) 除 \(A(x)\) 的商式,\(r(x)\) 称为余式。记做 \(A(x)\equiv r(x)\ (\bmod B(x))\)
特别的,若 \(r(x)=0\) ,则称 \(B(x)\) 整除 \(A(x)\)。
多项式的系数表示法: 将 \(n\) 次多项式 \(A(x)\) 的系数 \(a_0,a_1...a_n\) 看作 \(n+1\) 维向量 \(\overrightarrow{a}\)。
定理:
如果多项式 \(f(x),g(x)\) 的次数都不超过 \(n\) 。且对于它们 \(n+1\) 个不同的数 \(a_1...a_n\) 有相同的值,即
则 \(f(x)=g(x)\)
\(n+1\) 个点就能确定一个 \(n\) 次多项式。
如果选取 \(n+1\) 个不同的数 \(x_0,x+1,...,x_n\) 对多项式进行求值得到 \(A(x_0),A(x_1),...A(x_n)\) 那么就称 \(\{x_i,A(x_i): 0\leq i\leq n.i\in\mathbb{Z}\}\) 为多项式 \(A(x)\) 的点值表示。通过系数表示求点值表示的过程叫做求值,通过点值表示求系数表示的过程叫做求值。
为什么要用点值表示?
\(A(x),B(x)\) 在 \(x_0,x_1,...x_n\) 取值分别为 \(c_0,....c_n,d_0,...d_n\) 那么 \(A(x)*B(x)\) 取值为 \(c_0d_0,c_1d_1,...c_nd_n\)。
复数及其运算
虚数单位 : \(i=\sqrt{-1}\)
形如 \(a+bi(a,b\mathbb{R})\) 的数称为复数,\(a\) 称为实部,\(b\) 称为虚部,全体复数的集合--复数集用 \(\mathbb{C}\) 表示。
设 \(z=a+bi,w=c+b_i\)。
则有 \(z\pm w=(a\pm c)+(b\pm d)i\)
\(z*w=ac+adi+bci+bdi^2=(ac-bd)+(ad+bc)i\)
\(z/w=\frac{a+bi}{c+di}=\frac{(a+bi)(c-di)}{(c+di)(c-di)}=\frac{(ac+bd)+(bc-ad)i}{c^2+d^2}\)
共轭复数: \(\overline{z}=a-bi\) (虚数取反)
复数的集合意义:
复数对应平面直角坐标系上的点,横轴为实轴,纵轴为虚轴,\(a+bi\) 对应的点为 \((a,b)\)
复数对应的点到原点的距离称为复数的模长,即为 \(r=|z|\),由勾股定理,\(|z|=\sqrt{a^2+b^2}=\sqrt{z\overline{z}}\)
复数也可以用模长和幅角来表示。
复数与正半轴的角称为复数的幅角记为 \(\varphi=\arg z\)
所以 \(z=r(\cos \varphi+i\sin \varphi)\)
复数的几何意义,设 \(\vec{OA},\vec{OB}\) 分别为两个复数对应的向量,\(\vec{OX}\) 为运算结果对应的向量,复数的加减法遵循平行四边形定则,复数的乘法按照模长相乘,幅角相加的运算规则,除法为乘法的逆运算,共轭为对实轴的轴对称结果。
欧拉公式:
对于任意实数 \(x\) ,都存在
单位根
定义方程 \(z^n=1\) 的所有复数根称为 \(n\) 次单位根,这样的单位根共有 \(n\) 个,分别为:
这些单位根都分布在复平面的单位圆上,并构成一个正 \(n\) 边形,它们把单位圆分成 \(n\) 个部分。
本原单位根
快速傅里叶变换
传统的多项式乘法是 \(\mathcal{O}(n^2)\) 的,而且很难有优化空间,而多项式的点值表示法可以在 \(\mathcal{O}(n)\) 的时间内完成乘法,因此,如果能找到一种有效的方法在点值表示法和系数表示之间转化,就能高效计算。
快速傅里叶变换可以认为有两部分,DFT和IDFT。
FFT最常见的算法是 Cooley-Tukey 算法。
假设现在有一个 \(n-1\) 次多项式 \(A(x)=\sum\limits_{i=0}^{n-1}a_i*x^i\),为了方便设 \(n=2^m\),不足在高位补 \(0\) 。
将 \(n\) 个 \(n\) 次单位根 \(\omega_n^0...\omega_n^{n-1}\) 代入 \(A(x)\) 将其转换成点值表达 \(A(\omega_n^k)\)(待补)
Day 7
平衡树
二叉搜索树
左儿子子树内所有点的键值都比该节点键值小,右儿子内所有点的键值都比该节点键值大。
Splay
节点存的信息:
-
\(ch[0/1]\): 左、右儿子
-
\(fa\): 父亲节点
-
\(key\): 键值
-
\(cnt\): 键值为 \(key\) 的数字个数
-
\(siz\): 子树及其大小
旋转: 把儿子节点旋转到父亲节点上。
伸展: 把一个节点伸展到根节点上。
Luogu3369【模板】普通平衡树
Luogu3871 [TJOI2010]中位数
记录当前序列的数的个数,查询中位数排名。
Luogu1110 [ZJOI2007]报表统计
维护两个平衡树,一个维护原序列,第三问为查询前驱后继,另一个维护差值,对应第二问。
Luogu1503 鬼子进村
记录一下删除过的点,平衡树维护删除的点的集合,每次查询前驱后继。
Luogu3391【模板】文艺平衡树
平衡树维护每个数的下标,每个子树代表一个 \([l,r]\) 的区间,用懒标记标记当前区间是否需要反转。
如果没有 \([l,r]\) 的子树,可以搞出这样一棵子树: 把 \(l-1\) 旋转到根节点,\(r+1\) 到根节点的右儿子,可以发现根节点的右儿子的左儿子就是所需的区间。
在Splay上定位区间的一个常用方法,很多对区间询问和修改的操作可以这么实现。
Luogu5290[十二省联考2019] 春节十二响
特殊情况贪心的策略:将左右两条链的点,大的和大的合并,剩下的放在一个集合里面。
回到树上,把每个子树看成一条链,相当于对链进行合并。
Day8
(实际上是Day7)
第八天的在第七天的一块讲了。
字符串算法
Hash,KMP,字典树(挺简单就懒得记了233)
Luogu2463[SDOI2008]Sandy的卡片
先差分一下,求出每个从 \(S\) 开始的最长的公共子串,取最小值。
AC自动机
在Trie树进行KMP。
对于每个节点 \(u\) ,定义 \(fail[u]\)
\(fail[u]\) 指向Trie树上的一个点 \(v\) ,指向的节点的前缀和它后缀一样且长度最长的节点。
可以扩展 \(ch\) 的定义,在AC自动机上进行匹配时失配,不需要跳 \(fail\) ,直接跳 \(ch\) 即可。
求多个串在另一个串内出现的次数:
建出fail树,每个串的出现次数计数相当于从根节点到 \(x\) 节点都+1,可以看作给 \(x\) 节点+1,求子树 \(siz\) 即可。
Luogu2414[NOI2011]阿狸的打字机
Manacher
在S中相邻两个字符之间都插入一个'#'(没有出现过的特殊字符)
\(p[i]\) 为当前字符为对称轴时,能向左右延伸的最长长度。
假设已知 \(p[1..i-1]\) 求 \(p[i]\) 。
记 \(R\) 为当前向右延伸的最长长度。