两道题目运用了类似的思路,因此写在一起总结下。
HDU-6230
题目大意
给出长度为n的序列,问这个序列中有多少个长度为m的单调递增子序列。
解题思路
设 $DP[i][j]$ 表示长度为 $i$ ,最后一位为 $a[j]$ 的字符串个数
可以得到以下递推公式
$$
DP[i][j]=\sum_{k=i-2}^{j-1} DP[i-1][k]\space\space\space(a[k]<a[j])
$$
普通的算法时间复杂度为 $n^3$ ,无法满足要求
可以发现这个式子有两个不等式限制
$$
\begin{cases}
i-2<=k<=j-1 \\
a[k]<a[j]
\end{cases}
$$
即可在循环中每次最后把 $DP[i-1][j]$ 放入 $Bit[a[j]]$
下次循环中$j$增大,此时树状数组中的元素都满足第一个限制
在每次查询中求 $sum(a[j])$ 即满足第二个限制(此时 $Bit[a[j]]$ 位还没有放入)
HDU-5542
前面部分略过不讲,只关注最后不等式部分
需要求解有多少 $i,j$ 满足
$$
\begin{cases}
i<j\\
p[i]\leq j-i\\
p[j]\leq j-i
\end{cases}
$$
整理成
$$
\begin{cases}
i\geq j-p[j]\\
i<j\leq i+p[i]
\end{cases}
$$
每次循环把满足 $j-p[j]=i$ 的 $j$ 放入树状数组(借助vector<ll> g[]
)
随循环继续,$i$ 增大,此时树状数组中的元素都满足第一个限制
在每次查询中求 $sum(i+p[i])-sum(i)$ 即满足第二个限制