T1:
线性筛出前1e7个质数,暴力求出函数值。
由于输入可以当作随机数据处理,所以指针的变化是常数级别的,可以用指针维护位置。
开一个桶,维护每个数的数量,开两个指针变量,维护当前位置是哪个数和是第几个。
然后就可以分类讨论了,若删除和插入分别在两侧,指针就要移动。
等于的情况可以当作大于的情况,因为第二个指针是自下而上统计的。
时间复杂度$O(n)$。
T2:
假的博弈,每次一定取最大的。
可以动态维护最大值来做。
但是每次只加入一个数,也就是说如果新加入的数比当前集合的最大值更大,一定马上被取走。
于是我们可以开一个桶维护已选集合中的数,再用一个维护最大值。
发现这个指针是单调不降的,直接扫即可。
时间复杂度$O(nk)$。
T3:
考虑树形DP
由于路径不可逆,由上到下和由下到上的最优值不同。
分别开两个数组,$f[i][j]$代表由子节点到达$i$,撒了$j$团面包屑的最优值;$g[i][j]$代表由$i$到达子节点,撒了$j$团面包屑的最优值。
然后用这两个数组维护前缀最大值,枚举lca及两侧分别用的面包屑数,就能得出最优答案。
维护每个节点连接的节点总的鸽子数$s[i]$,可以进一步优化转移。
从每个节点开始或结束:
$f[i][j]=max(f[i][j],s[i])$
$g[i][j]=max(g[i][j],s[i]-a[fa])$
撒下一团面包屑:
$f[i][j]=max(f[i][j],f[son][j-1]+s[i]-a[son])$
$g[i][j]=max(g[i][j],g[son][j-1]+s[i]-a[fa])$
不撒面包屑:
$f[i][j]=max(f[i][j],f[son][j])$
$g[i][j]=max(g[i][j],g[son][j])$
时间复杂度$O(nv)$。