Trick
liduoduo2021 · · 算法·理论
From [20240922] 洗牌
对于01串做不相交区翻操作,可以再log次以内完成,每次合并相邻的一段一。
From [20240916] 序列
序列区间减归零问题除了单调栈、笛卡尔数,还应该想到差分。
From [20240908] 随机游走
期望转移中,如果存在未知量,可以用线段树记录系数,在往上合并的过程中不断消元。
From [20240928] 排列
首先对于只存在一个排列的方案数就是错排的方案数。可以转化为
sol1:容斥
具体的:
sol2:递推
除此之外,还有递推的做法,令
可以理解为,从1到n-1中选取1个数放到n的位置上,令其为k,将n当做k则有
两个排列时,可以先将
与之前的容斥一样,我们只需要求出
由这题还可以得到的一个技巧是,二选一可转化成图论。
From [20241015] 棋盘游戏
棋盘上,当条件为每行每列只能出现一个元素的时候,可以考虑二分图。
From [20241017] 开发者选项
询问某个区间是否被覆盖可以转化为对于每个点去求覆盖它的区间。
From [20241004] 粉刷
棋盘上每次操作行或列,若要使每个点都被覆盖,一定会有其中一种操作是操作了所有的。
From [20241002] 合并数字
对于合并两个数的操作,每队合并关系可以建边,由此得到一颗树,此树的层数可能会和操作次数的多少和权值挂钩。
From [20241019] 循环涂色
每位可选元素为整数集合,求使得任意相邻两个和首尾两个不同的方案数。
有两种方法可以解决此问题,令位置有
sol1
其中
sol2
考虑原问题是否可以容斥,当不考虑第一位时,不合法的方案就是第一个与最后一相同的方案数,也就是条件为
形式化的,令
可以递归处理。
这两部分结合起来就可以在
From Prufer序
给定每个数的度数,构建原树。因为有
所以可以每次取出度数最大的两个数,将它们连一条边,然后将它们的度数减一,此操作可以用堆实现。证明可以看一些结论中的第一个。
From [20241109] 最大独立集
对于询问
sol1 扫描线:
移动右端点带来的影响如果好计算的话就可以枚举右端点,左端点数据结构维护。时间复杂度
sol2 矩阵:
矩阵每次需要完成的是从上一位到这一位的转移,累计答案,和新增一个起点,但是有取
sol3 cdq分治:
对于cdq分出来的左右区间,当左端点在左区间右端点在右区间时,是可以覆盖所有区间的。考虑cdq是否能做就是看
upd on 20250108
sol4 整体二分
From [Ynoi Easy Round 2021] TEST_152
关于区间段覆盖问题,代码用set维护可以这样写,时间复杂度
inline auto split(int pos){
auto it=s.lower_bound((node){pos,0,0});
if(it->l==pos)return it;
it--;
int l=it->l,r=it->r;
ll x=it->x;
s.erase(it);
s.insert((node){l,pos-1,x});
return s.insert((node){pos,r,x}).first;
}
inline void ins(int l,int r,int x){
auto itr=split(r+1);
auto itl=split(l);
//现将 l,r+1 点作为断点,使得删除的都是整区间
for(auto it=itl;it!=itr;it++){
ll nl=it->l,nr=it->r,nx=it->x;
删除当前 [nl,nr] 区间的影响
}
s.erase(itl,itr);
//删除 [l,r] 之间的区间
s.insert((node){l,r,x});
加入当前 [l,r] 区间的影响
}
upd2024.12.1 :意识到这就是ODT。
From 「CEOI2019」魔法树
对于形如:
的树上问题转移。可以用线段树合并完成。新加入的
From ARC187 B-Sum of CC
对于存在多种序列,每种序列的权值为划分区间的个数,求所有序列的全职和的问题可以转化为求所有对于
From [20241113] 排列计数
对于一个排列重拍,计算其任意两个相邻下标数值不相邻的个数。考虑容斥,首先会想到求分别有
From [20241113] 冒泡排序
对于求所有权值和的问题,可以改成求大于
From [20241119] 标号
对于一个联通图,删去一个边集,使两点不联通。可以从其中一个点跑一边最短路,然后可以发现对于与起点距离相同的点,删去这些点连出去的顺向边以后,到终点一定不联通,考虑反证,若删去以后终点所在点集与起点所在点集有连边,那么一定存在一条路径上,存在当前点权的 点能连向终点。
From [20241123] 挑战 RSA
对于
From 【AC自动机】背单词
关于暴力定期重构的除了每
From QMT3
对于两颗子树的并的信息,除了用线段树合并维护另一颗树的dfs序以外,还可以转化成两个偏序条件,用cdq来做。
From [20240227] 隧道
对于求解最短路径过程中存在一种包含很多数的操作,可以每次取特殊操作维护的极值和堆维护的极值取更优的作为当前更新节点。例如此题结合了堆与李超树,注意要支持删除操作。
From [20250226] 位运算
维护一个
for(int step=0;step<li;step++){
for(int i=0;i<1<<li;i++)for(int j=0;j<=li;j++)for(int k=0;k<=li;k++)g[i][j][k]=f[i][j][k];
for(int i=0;i<1<<li;i++){
for(int j=0;j<=li;j++){
for(int k=0;k<=li;k++){
if((1<<step)&i){
f[i][j][k]=g[i][j][k-1]+g[i-(1<<step)][j][k];
}else{
f[i][j][k]=g[i][j][k]+g[i+(1<<step)][j][k];
}
}
}
}
}
From 20250310 ARC194 B
关于使用交换操作使得序列有序求代价,可以考虑每个逆序对贡献。
From nkoj8316 买酒卖酒
对于一个最大流模型,可以转化为求解它的最小割划分,用动态规划的方法,求出点集划分最小代价。
注意:原问题可能是求解最大值,通过转化之后就是求解最小值。
From nkoj9943 出好题
莫队中对于一个数的变化值只有1,所以处理形如
From nkoj9946 易碎树
对于分别维护了直径的两颗子树合并时,新的直径端点一定是其中组合而成。
From 20250620 abc
可转化成:
From 20250623 Żelki
对于类似完全背包的问题,可以把转移建边,最短路即为答案。