2025.7.15
李超树



如果不相交,就留最高的,否则。



线段树合并
先动态开点。
要只有左儿子或右儿子的线段树。
合并的时候,如果节点都有,就只保留一个,否则保留两个,然后push_up的时候就会更新正确答案。


树链剖分



DP




















点击查看代码
int dp[100][1<<12];
// dp[i][mask] 表示目前考虑了前i组内的所有数
// 使用了的质因数为mask
// 的情况下,最优答案
// 假设输入
// 2, 3, 6, 12, 66, 33, 22, 17, 60, 74, 111, 39, 410
// 1. 先分组
(2, 3, 6, 12, 66, 33, 22, 17, 60, 39) //特殊组 没有 33 以上的质因数
// 37的组
(74, 111)
// 41的组
(410,)
// 43 的组
()
// 47 的组
()
// ....
vector<int> vec[1001]; // 存储每一组 0是特殊组
// 2. DP 处理特殊组
for(auto x: vec[0])
for(int mask=0;mask<(1<<12);mask++){ // 已经使用过的质因数
// 如果 mask 含有x的所有质因数
// mask 去掉x含有的质因数 后为 mask2
dp[0][mask] = max(dp[0][mask], dp[0][mask2] + 1);
}
// 3. DP 转移后续的组
for(int i=1;i<=1000;i++){
for(int mask=0;mask<(1<<12);mask++){ // 已经使用过的质因数
dp[i][mask] = dp[i-1][mask]; // 啥都不选
}
for(auto x: vec[i])
for(int mask=0;mask<(1<<12);mask++){ // 已经使用过的质因数
// 如果 mask 含有x的所有质因数
// mask 去掉x含有的质因数 后为 mask2
dp[i][mask] = max(dp[i][mask], dp[i-1][mask2] + 1);
// 因为是从 dp[i-1] 添加一个 x 得到 dp[i]
}
}
// 4. 答案就是 dp[1000] 的最大值

浙公网安备 33010602011771号