Loading

来自某学长

New
//树的直径、树的重心
//启发式搜索(A*)
//迭代加深搜索
//点分治
//树分块
//虚树
//Splay
//带权并查集
//凸包
//可持久化线段树
//*prufer编码
//*动态点分治
//可持久化trie
//边分治
//整体二分
//*树上莫队
//CDQ分治
//trie图DP
//向量的点积/叉积
//动态树
//二维线段树
//Lucas定理
//矩乘优化
//单调队列优化
//期望DP
//模拟退火
//爬山算法
//*后缀自动机(sam)
//后缀数组(sa)
//*后缀树
//*回文自动机
//*KDtree
//基环树DP
//斜率优化
//*半平面交
//*旋转卡壳
*三角剖分
*插头DP
//倍增优化
//*四边形不等式优化
//莫比乌斯反演
//FFT
//线性代数(行列式)
//*仙人掌算法

单纯形法解线性规划
*其它可持久化数据结构

NEW 

REVIEW
后缀数组/自动机
回文自动机
KD-tree/prufer/lucas/fft
旋转卡壳/半平面交/凸包



Tips
欧拉函数(小于x的互质数个数)
1.
	f[x]=x*(1-1/x1)*(1-1/x2)*....*(1-1/xn)
	其中x1...xn为x的质因数
2.	
	f[x]=x-1(x为质数)
3. 
	线性筛:令j为质数
	若i%j==0 phi[i*j]=phi[i]*j;
	否则 积性函数:phi[i*j]=phi[i]*phi[j];

欧拉ext:a^b同余a^((b%phi[p])+(b>=phi[p]?phi[p]:0))(mod p)
欧拉定理 x^phi(y)%y=1 当y为质数时即费马小定理

判素数 rubbin miller
对于p 将x=p-1 分解为2^n*k
对于一个尝试a
从a^k开始平方直到等于a^(2^n*k)
若a^(2^x*k)=1(mod p) 则判断 a^(2^(x-1)*k)是否等于1或p-1

pollard_rho(ll n, int a){
    ll x = 2, y = 2, d = 1;
    while(d == 1){
        x = mul_mod(x, x, n) + a;
        y = mul_mod(y, y, n) + a;
        y = mul_mod(y, y, n) + a;
        d = __gcd((x >= y ? x - y : y - x), n);
    }
    if(d == n) return pollard_rho(n, a + 1);
    return d;
}

由于数字过大需要快速加 即x*y运算分解成2进制
注意随机数
检验质数时的数不能是自己

莫比乌斯反演
约数的莫比乌斯反演: 
若:f(n)=∑d|n g(d) 
则:g(n)=∑d|n μ(d)f(n/d) 
倍数的莫比乌斯反演: 
若:f(n)=∑n|d g(d) 
则:g(n)=∑n|d μ (d/n)f(d)

公式中的μ(x)是莫比乌斯函数,它是这样定义的: 
μ(x)=1  x=1
μ(x)=0  x存在平方因子
μ(x)=?1 x有奇数个质因子(包括x是质数)
μ(x)=1  x有偶数个质因子

-------------------------------------------------------

2-sat问题
按题意连边
求强连通分量后将所有边取反(此时若一个块不选,则边连向的块都不能选)
把A,A’所在的块标上矛盾
按边拓扑排序,每次取出一个可以选的块,把与其矛盾的块标记为不可选,同时从矛盾的块
开始延边dfs,dfs到的块均不可选.

求最小字典序解
1)给每个点设置一个状态V,V=0表示未确定,V=1表示确定选取,V=2表示确定不选取。称一个点是已确定的当且仅当其V值非0。设立两个队列Q1和Q2,分别存放本次尝试选取的点的编号和尝试不选的点的编号。
(2)若图中所有的点均已确定,则找到一组解,结束,否则,将Q1、Q2清空,并任选一个未确定的点i,将i加入队列Q1,将i'加入队列Q2;
(3)找到i的所有后继。对于后继j,若j未确定,则将j加入队列Q1;若j'(这里的j'是指与j在同一对的另一个点)未确定,则将j'加入队列Q2;
(4)遍历Q2中的每个点,找到该点的所有前趋(这里需要先建一个补图),若该前趋未确定,则将其加入队列Q2;
(5)在(3)(4)步操作中,出现以下情况之一,则本次尝试失败,否则本次尝试成功:
<1>某个已被加入队列Q1的点被加入队列Q2;
<2>某个已被加入队列Q2的点被加入队列Q1;
<3>某个j的状态为2;
<4>某个i'或j'的状态为1或某个i'或j'的前趋的状态为1;
(6)若本次尝试成功,则将Q1中的所有点的状态改为1,将Q2中所有点的状态改为2,转(2),否则尝试点i',若仍失败则问题无解。
该算法的时间复杂度为O(NM)(最坏情况下要尝试所有的点,每次尝试要遍历所有的边),但是在多数情况下,远远达不到这个上界。
具体实现时,可以用一个数组vst来表示队列Q1和Q2。设立两个标志变量i1和i2(要求对于不同的i,i1和i2均不同,这样可以避免每次尝试都要初始化一次,节省时间),若vst[i]=i1则表示i已被加入Q1,若vst[i]=i2则表示i已被加入Q2。不过Q1和Q2仍然是要设立的,因为遍历(BFS)的时候需要队列,为了防止重复遍历,加入Q1(或Q2)中的点的vst值必然不等于i1(或i2)。中间一旦发生矛盾,立即中止尝试,宣告失败。

树的直径:从任意一点u处bfs找最远点x 从x处bfs找最远点y xy即为树的直径
树的重心:树形dp

建虚树:
关键点按dfn序排序
for(int i=1;i<=n;i++){  
    int lca=getlca(stk[top],lux[i].x);  
    while(deep[lca]<deep[stk[top]]){  
        if(deep[stk[top-1]]<=deep[lca]){  
        	int last=stk[top--];  
            if(stk[top]!=lca)stk[++top]=lca;  
            G.add(lca,last);  
            break;  
        }  
        G.add(stk[top-1],stk[top]),top--;  
    }  
    if(stk[top]!=lux[i].x)stk[++top]=lux[i].x;  
}  
while(top)G.add(stk[top-1],stk[top]),top--;  

lucas定理:
c(n,m)%p=c(n%p,m%p)*c(n/p,m/p)%p 

splay区间平移:
ab平移c个单位=
翻转a,b
翻转a,a+c-1
翻转a+c,b

lower_bound 大于等于x的第一个位置
upper_bound 大于x的第一个位置

prufer编码:
1.一棵标号树的Pufer编码规则如下:找到标号最小的叶子节点,输出与它相邻的节点到prufer 序列, 将该叶子节点删去,反复操作,直至剩余2个节点。
2.设点集V={1,2,3,...,n},每次取出prufer序列中最前面的元素u,在V中找到编号最小的没有在prufer序列中出现的元素v,给u,v连边然后分别删除,最后在中剩下两个节点,给它们连边。最终得到的就是无根树。
3.prufer序列中某个编号出现的次数就等于这个编号的节点在无根树中的度数-1

huffman_tree:
k叉树的最小带权距离
先补成满k叉树 即n%(k-1)==1
每次取出最小k个节点 生成新节点 值为这些节点的和

完全二分图的生成树计数k(n,m)左n右m
=n^(m-1)*m^(n-1)

矩阵树定理:
令矩阵A=度数矩阵-临接矩阵(度数矩阵除对角外都为0)
矩阵生成树即A的主子阵求行列式(主子阵即消掉任意x的x行x列)
行列式求法:消元为上三角行列式 对角线乘积即答案

树上莫队
(x,y) -> (x',y')
lcaX=lca(x,x')
lcaY=lca(y,y')
取反(x->lcaX) (x'->lcaX) 不包括lcaX
取反(y->lcaY) (y'->lcaY) 不包括lcaY
取反lca(x,y),lca(x',y') 

kmp:
初始化fail[0]=fail[1]=0;
从1开始for 如果s[迭代的fail]=s[自身] i+1的fail为cur+1

AC自动机指针版:
root及root下一层fail都为root
bfs时
若有这个子节点 则子节点的fail指针为次节点的fail节点的对应子节点
否则 子节点改为fail指针的对应子节点(若为NULL则为root)
匹配时 直接进入下一点 若进入NULL则转到root
从此点开始跳转 当跳到root或cnt=-1时停止

割点割边(无向图):
割点:u!=root && low[v]>=dfn[u] || u==root && child==2
割边:low[v]>dfn[u] edge(u,v)为割边 传入fa

线性筛逆元:
inv[1]=1;rep(2,n) inv[i]=(p-p/i)*inv[p%i])

原根:
一个数m如果有原根,则其原根个数为phi(phi(m))。特别地,对素数有phi(p)=p-1。
int k=phi(m)
若所有p^(k/k的质因数)mod m !=1 则 p为m的原根

复数相乘的几何含义是 极角相加 长度相乘 对应旋转和缩放
相除 极角相减 长度相除 
a+bi/c+di=(ac+bd)/(c^2+d^2)+(bc-ad)i/(c^2+d^2)
除法将分子分母同时乘c-di 分母化为实数

中国剩余定理:
M[i]=所有m的乘积/m[i]
ans=Σa[i]*M[i]*inv(M[i],m[i])
a为余数 m为除数

差分约束:
a-b<=c 从b向a连一条长度为c的边
求最短路 dis[s][t]即为最大值
a-b>=c 从b向a连一条长度为c的边
求最长路 dis[s][t]即为最小值
若dis[s][t]没被更新 无穷解
若有负环 无解

manacher:
pos为对称轴中心 maxright为对称最右位置
if(i<maxright)
l[i]=min(l[2*pos-i],maxright-i)
else 
l[i]=1;
然后暴力扩展 注意边界

欧拉回路:
无向图:每个顶点的度数都是偶数,则存在欧拉回路。
有向图:每个顶点的入度都等于出度,则存在欧拉回路。
欧拉路径:
无向图:当且仅当该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。
有向图:当且仅当该图所有顶点 出度=入度 或者 一个顶点 出度=入度+1,另一个顶点 入度=出度+1,其 
他顶点 出度=入度。

混合图的欧拉回路:
先为所有无向边规定一个方向(x,y) chu[x]++,ru[y]++并在网络流中连一条(y,x,1)的边
其他有向边 chu[x]++,ru[y]++;
最后对所有点 若ru[i],chu[i]奇偶性不同 则无解 否则
if(ru>chu) 连(s,i,(ru-chu)/2)
else 连(i,t,(chu-ru)/2)
求最大流==s出去的流量? 

求二分图最大权匹配km算法:
先把每个x附上lx(连出去所有边最大的权值)
对于每一个x尝试hungary找最优找不到时调整lxly
取d=所有未便利的y的slack最小值
将所有lx-d ly+d
hungary过程如下:
对于一个x能到的所有y 若lx[x]+ly[y]=w[x][y] 则正常2分图匹配
否则 slack[y]=min(slack[y],lx[x]+ly[y]-w[x][y])

最小点覆盖:对于图G=(V,E)中的一个点覆盖是一个集合S?V使得每一条边至少有一个端点在S中。
二分图:最大匹配

最小边覆盖:使该图上每一节点都与这个边子集中的一条边关联
二分图:n-最大匹配

最小路径覆盖:选n条路径 覆盖所有点
对DAG可转换为二分图上的n-最大匹配
不可相交路径:若有边x->y 将x1连向y2 即拆点保证路径不重复
可相交路径:如果x->y有路径 将x1连向y2

最大独立集:选n个点 两两之间没有边
二分图:n-最大匹配
一般图:补图的最大团

最大团:NP完全问题 模拟退火

最大权闭合子图:
最大权闭合子图指选择u,则u以下关系的都要选,一定要选到底,不能跳过u选它以下的。增设一个超级源点和一个超级汇点,(1->n)的点中,当点权为正时,从源点向该点连一条权值为点权大小的边,当点权为负时,从该点连一条权值大小为它的绝对值的边连向汇点。这种问题一般都是对于(u,v),如果选择u必须选择v,对(u,v)连一条容量为oo的边。
答案数等于靠近源点最小割一边的点数,最大利益=所有点正权值之和-最小割。
对于一个图,我们可能会有多种割法得到的最大权封闭子图的价值相等。

求所得最大权子图中的所有点:遍历源点能到达所有点,能遍历到说明其点在子图中,什么叫能遍历到呢?就是检查残余网络中的边和反向边,若(u,v)边权大于0,则说明u能到达。

这样能遍历到的一定是点数最少的最大权封闭子图

如何求最多能遍历到一种类型的点在最大价值下最多能有多少个呢,比如有梦想和付出,完成梦想可以得到价值,完成付出需要消耗价值,如何求在得到最大价值的情况下最多能得完成多少个梦想呢。

给所有连接到源点汇点的边权乘一个较大的常数,另给连接到源点的梦想的边权加1,这样弄一遍网络流,得到的最大价值除一个较大的常数就是我们需要的价值,源点能到达的梦想就是最大梦想。


退火算法:
温度高时 贪心
温度低时 更优解->接受 更差解->概率决定

爬山算法:
温度高时 贪心
温度低时 更优解->接受 更差解->不接受

后缀自动机:
构建时 cur开始跳fa直到有c这个儿子
若跳到0
	则fa[cur]=1;
否则 q=p的这个儿子
	若len[q]==len[p]+1 fa[cur]=q;
	否则 
		新建tmp ch[tmp]=ch[q] len[tmp]=len[p]+1;
		fa[tmp]=fa[q];fa[q]=fa[cur]=tmp;

性质1:从last开始跳fa到达的点均为后缀结束节点
性质2:所有不同路径对应不同字串
性质3:以某节点结束的路径为 以此节点为结束为止的后缀
性质4:以某节点p结束的路径长=(len[fa[p]],len[p]]=此节点结束的字串个数

后缀数组:
Str :需要处理的字符串(长度为Len) 
Suffix[i] :Str下标为i ~ Len的连续子串(即后缀) 
Rank[i] : Suffix[i]在所有后缀中的排名 
SA[i] : 满足Suffix[SA[1]] < Suffix[SA[2]] …… < Suffix[SA[Len]],即排名为i的后缀为Suffix[SA[i]]
Height[i] : 表示Suffix[SA[i]]和Suffix[SA[i - 1]]的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀 
H[i] : 等于Height[Rank[i]],也就是后缀Suffix[i]和它前一名的后缀的最长公共前缀

->按照H[1]、H[2]……H[Len]的顺序进行计算即可O(len)时间计算出height数组
->基数排序(倍增)求rank
->一个串里不同子串的个数=∑(n?sa[i]+1?height[i])
->两个排名不相邻的最长公共前缀定义为排名在它们之间的Height的最小值。
->所有排好序的后缀取不同前缀 即为 所有排好序的不同子串

树分块3种:
1 直接对dfs分块 用于树上莫队
2 递归栈分块 把当前点看成栈底 若处理完子树后栈中元素>M则一起加入新块 把自己加入栈
3 若父亲所在的块没满 加入父亲的块 否则创建新块并连接父亲的块

树上莫队:
x y -> x' y'
即x->x' y->y'
把x到lca(x,x')(不包括这个点)取反
把x'到lca(x,x')(不包括这个点)取反
把y到lca(y,y')(不包括这个点)取反
把y'到lca(y,y')(不包括这个点)取反
把lca(x,y)取反
把lca(x',y')取反

lct:
fa[x]=y表示在原树中x与y有边连接且fa[x]=y
son[x][0]=y表示x,y在一个splay中且在原树中x深度比y大
在一个splay中则原图必然连接 但原图连接不一定在一个splay中
维护标记时注意size的影响 rev标记不当时执行 pushdown时执行
access操作代表提出x到根的这条链作为lca
判断两点是否联通 用find找所在树根
判断两点是否直接相连 要保证深度关系的同时 中间没有点
rot时 若f不是splay的根 才能让g的儿子变成x

回文树:
节点信息 len to[26] sufflink(指向最长后缀回文串)
初始化num=2;suff=2;
tree[1].sufflink=1,tree[1].len=-1;
tree[2].sufflink=1,tree[2].len=0;
*当加入新回文串长度为1时 sufflink指向2 这样可以匹配偶数长度

KD-tree:
查询k维平面上任意点到给定点集合的最近距离和最远距离
2维平面为例
分割为若干平面 先走到叶节点 将此距离作为ans画圆
回溯过程中若圆与另一子树表示的平面相交 在里面查找

基环树DP:
并查集找环
去掉环上任意一条边之后考虑乱搞
注意考虑去掉边对答案的影响

斜率优化:
写出dp式 将与i有关的放在一边
为了o(1)复杂度 每次只取队首元素当作最优解
->如何保证队首最优
->保证head比head+1优 head+1比head+2优....(当队列中所有线段均满足不等式时,head所在的线段满足则之后线段均满足->利用上凸/下凸性质)
->维护上凸或下凸
->当队首不满足目前不等式时 head++ 直到满足 因为上凸/下凸性质 head之后的点均满足不等式 故head最优
->用队首更新当前点
->判断当前点与tail,tail-1的关系 维护凸包 在合适位置加入当前点

四边形不等式优化:
形式
m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(i≤k≤j)(min也可以改为max)
上述的m(i,j)表示区间[i,j]上的某个最优值。w(i,j)表示在转移时需要额外付出的代价。

需要满足要求
1.区间包含的单调性:如果对于i≤i'<j≤j',有w(i',j)≤w(i,j'),那么说明w具有区间包含的单调性。(
2.如果对于i≤i'<j≤j',有w(i,j)+w(i',j')≤w(i',j)+w(i,j')

优化方案:s(i,j-1)≤s(i,j)≤s(i+1,j)。即原来的状态转移方程可以改写为下式:
m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(s(i,j-1)≤k≤s(i+1,j))(min也可以改为max)

半平面交(evails):
step1. 将所有半平面按极角排序,对于极角相同的,选择性的保留一个。 O(nlogn)
step2. 使用一个双端队列(deque),加入最开始2个半平面。
step3. 每次考虑一个新的半平面:
a.while deque顶端的两个半平面的交点在当前半平面外:删除deque顶端的半平面
b.while deque底部的两个半平面的交点在当前半平面外:删除deque底部的半平面
c.将新半平面加入deque顶端
step4.删除两端多余的半平面。
具体方法是:
a.while deque顶端的两个半平面的交点在底部半平面外:删除deque顶端的半平面
b.while deque底部的两个半平面的交点在顶端半平面外:删除deque底部的半平面
重复a,b直到不能删除为止。
step5:计算出deque顶端和底部的交点即可。
这个算法描述的非常清晰。当初写的时候有两个地方想的不太明白:step 1如何选择性的保留一个。step3如何判断交
点在半平面外。
其实这两个问题都可以用叉积来解决。首先根据给定的两点顺序规定好极角序。假定两点o1o2的输入方向是顺时针,那
么另一点P是否在其平面内只要判断o1P这个向量是否在o1o2这个向量的右手边即可。对于相同角度的两个半平面
(a1a2,b1b2),可以看a1b1这个向量是否在a1a2这个向量的右手边,每次都要选择更靠近右手边的那个半平面。

计算几何常用函数:
—————————————————————
atan2 比atan稳定 求极角
atan2(y,x)->原点到(x,y)的方位角->(-π,π]
—————————————————————
int doublecmp(double x){
	if(fabs(x)<eps) return 0;
	return x>0?1:-1;
}
—————————————————————
ab*ac(向量叉积) multi(point a,point b,point c)
叉积:x1*y2-x2*y1;
 =|ab|*|ac|*sin? ?为ab逆时针到ac的夹角
—————————————————————
a*b=|a||b|cos? ?为向量a旋转到向量b经过的夹角
数值=x1*y1+x2*y2;几何意义为向量a在b上的投影乘b的模长
—————————————————————
求任意凸多边形的面积
法则是(逆时针坐标乘积-顺时针坐标乘积)÷2
[(x1*y2+x2*y3+x3*y4+x4*y5+x5*y1)-(x1*y5+x2*y1+x3*y2+x4*y3+x5*y4)]/2
—————————————————————
求两直线交 算叉积算三角形面积 面积比等于长度比
推算交点坐标 同两线段相交写法
—————————————————————
已知两点坐标(x0,y0),(x1,y1)直线解析式为
ax+by+c=0 其中a=y0-y1,b=x1-x0,c=x0*y1-x1*y0
两直线求交点时
x = (b0*c1 – b1*c0)/D
y = (a1*c0 – a0*c1)/D
D = a0*b1 – a1*b0, (D为0时,表示两直线平行)
—————————————————————
查询一个点在凸包内
按极角序二分出在那两个点之间 判断是否在该线段内侧
—————————————————————
一个斜率为k的直线从正无穷处向下平移 问碰到的点
在凸包上二分斜率
—————————————————————
造凸多边形 随机若干和为0的向量 按极角排序后首尾相接
—————————————————————

线性基:
从1到log行 第i行代表的数是1<<(log-i)
若insert的数包含这行对应的数:
1o 若已被占 ^
2o 占领此行 用后面消干净这行 用这行消干净前面

第二类斯大林数
<<<<<<< HEAD
x^n=∑(i=1……n)S(n,i)?F(x,i)
S(n,i)=S(n?1,i)?i+S(n?1,i?1)
=======
xn=∑ni=1S(n,i)?F(x,i)
S(n,i)=S(n?1,i)?i+S(n?1,i?1)

康托展开为:
(an-1)*(n-1)!+(an-1-1)*(n-2)!+……+(a1-1)*0;
其中ai表示第i个元素在未出现的元素中排列第几

博弈论 sg函数    
mex(x)=min未出现在{mex(y)(y为x可达状态)}的自然数
阶梯nim游戏 奇数层亦或和 偶数层不考虑

二进制枚举子集
对于x的所有子集
for(int i=x;i;i=(i-1)&x)

时间复杂度估算
O(n) 1e7
O(nlogn) 1e5 - 5e5
O(n^2) 1000-5000
O(n^3) 200-500
O(n^2logn) 1000

构造题
从%4=0的数开始异或4个 异或和为0
根据这个性质构造异或和

树的直径若为偶数 则有必经点
若为奇数 则有必经边
把必经点作为根 深度为D/2的点可能是端点
当且仅当 端点所处的根的不同子树集合只有1个未被删光时
直径才会改变

在置换群中的 Burnside 引理:如果按照一定要求,要对1到n 的位置染色,那么本质不同的染色方案数为置换群中每个置换的不动染色方案数的平均数。
来解释以下,本质不同的染色方案是指,两个染色方案不能通过置换群中的任意置换变换使其相同,那么它们就是本质不同的。
某个置换的不动染色方案数是指,用这个置换变换之后没有发生变化的染色方案。

最小生成树中
权值为x的边选了y条
保留权值不为x的边
则将这y条换成另y条权值x的边 若仍无环 则可成为新的最小生成树
同时权值不同的边之间不相互影响

bitset:
flip()反转01
flip(x) 指定第x位
set()全设为1
reset()全设为0
none() 全为0?
any() 有1?
to_ulong() 
to_string()
[]直接访问某一位
count()返回1的个数
可用()方式赋值
括号内为usigned long 或 string
超过位数不计入 少的位数补0

fwt模版
t0=f[j],t1=f[j+gap]
rev=inv(2,mod);
正运算 
xor f[j]=(t0+t1)%MOD,f[j+gap]=(t0-t1)%MOD
and	f[j]=(t0+t1)%MOD;
or	f[j+gap]=(t0+t1)%MOD
逆运算
xor f[j]=(t0+t1)*rev%MOD,f[j+gap]=(t0-t1)*rev%MOD
and	f[j]=(t0-t1)%MOD;
or	f[j+gap]=(t1-t0)%MOD

bitset
当作全是01的长数组 可以左移右移 位运算

平衡树
维护权值与维护序列一样
在插入时就决定了
在树上根据形状决定其地位 而非val
insert和del时若有返回值 要仔细

huffman tree:
定义:给定n个权值的节点作为叶节点 构造带权最小2叉树
初始化n个根节点为权值的树
每次取出根节点权值最小的两个树合并
产生的新根为2根之和

huffman 编码
将n个叶节点用01串表示(从根开始的路径 左为0 右为1)
则对应的01串是平均长度最短的唯一编码表示法(叶节点权值代表出现次数)
eg: 信息a将出现7次 b将出现5次 c将出现9次 将句子用可唯一拆分的01串表示
则将叶节点权值设定为出现次数 对应huffman编码即答案

判定一个竞赛图
把出度排序
对于每一个k属于1-n
都有du[1]+du[2]+...+du[k]>=c(k,2)

可持久化数据结构
可以直接使用之前的节点
但是不能修改之前的节点信息
例如可持久化treap中可以直接return上次的节点
但是修改左右子树时需新建节点对其进行操作
注意内存!

次小生成树:
先求最小生成树
然后考虑把一条边替换进去
设边x->y 求出最小生成树中x到y的路径上的最大边权
代价为其差

左偏树:
定义一个点的深度为到最深叶节点到他的距离(同avl)
合并两堆时 将权值较小的根节点作为根
另一根向他的右子树插入 插入完后考虑是否交换左右子树并维护深度

catalan数
例子:有2*n个括号 其中有n个( n个) 排成一列的匹配方案
初始值c(0)=1;
递推:c(n)=sum(c(n-1-i)*c(i))(i=0....n-1)
通项:c(n)=ch(2n,n)/(n+1) ch表示组合数

第一类斯特林数s(p,k)
解释:n个人分成k组做环排列的方法数
s(p,0)=0,p>=1
s(p,p)=1,p>=0
s(p,k)=(p-1)*s(p-1,k)+s(p-1,k-1)
递推关系的说明:
考虑第p个物品,p可以单独构成一个非空循环排列,这样前p-1种物品构成k-1个非空循环排列,方法数为s(p-1,k-1);
也可以前p-1种物品构成k个非空循环排列,而第p个物品插入第i个物品的左边,这有(p-1)*s(p-1,k)种方法。

第二类斯特林数s(p,k)
定义:把n个数放进k个无差异的盒子里的方法数
显然盒子有差异时的发案数即乘上k!
s(p,k)=s(p-1,k)*k+s(p-1,k-1);
s(p,p)=1,p>=0
s(p,0)=0,p>=1

注意预处理逆元
若式子中包含除以0这一项 则逆元法无效
且从大于mod的地方开始逆推阶乘逆元无效
须用lucas定理 且从mod-1开始逆推阶乘逆元

拉格朗日插值
(x0,y0) (x1,y1).....

(x-x1)*(x-x2)...*(x-xn)
----------------------- y0 + .....
(x0-x1)*(x0-x2).*(x0-xn)

对两个向量判谁左谁右
不能直接比较端点的x
而是用叉积

cdq问题
相同的需要合并 否则之间的影响无法统计
最外层的排序一定要多维都排完 保证只有前面对后面有影响
可以用归并代替内部的sort
可以套bit

可删除的优先队列:
结构体里放两个优先队列 cur 和 del
重载top pop等函数

看stl函数!!

posted @ 2022-07-14 09:26  Into_qwq  阅读(22)  评论(0编辑  收藏  举报