1 条题解
-
0
自动搬运
来自洛谷,原作者为

紫题
**搬运于
2025-08-24 21:27:22,当前版本为作者最后更新于2019-03-23 21:03:09,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这道题可以拓展到M元上升子序列。
做法: DP + 树状数组优化
仿照的做法,设为以为结尾的长度为的上升子序列的个数。
得到状态转移方程:
转移时暴力枚举,显然复杂度为
考虑到k有两个限制条件,和,可以先将离散化,再用树状数组维护。
具体来说,在外层循环,建立一个树状数组,以为下标存储的值。当内层循环到时,,然后在转移到下一个之前。 从小到大循环保证了,查询的前缀和保证了。
复杂度。
双倍经验:UVA12983#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; ll n, a[30010], s[30010], m, f[4][30010], c[60010], ans; ll val(int x) { return lower_bound(s+1, s+m+1, x) - s; } ll ask(int x, ll sum = 0) { for(; x; x -= (x & (-x))) sum += c[x]; return sum; } void add(int x, ll v) { for(; x <= m; x += (x & (-x))) c[x] += v; } int main() { cin >> n; for(int i = 1; i <= n; i++) cin >> a[i], s[i] = a[i]; sort(s+1, s+n+1); m = unique(s+1, s+n+1) - s - 1; for(int i = 1; i <= n; i++) f[1][i] = 1, a[i] = val(a[i]); for(int i = 2; i <= 3; i++) { memset(c, 0, sizeof(c)); for(int j = 1; j <= n; j++) { f[i][j] = ask(a[j]-1); add(a[j], f[i-1][j]); } } for(int i = 1; i <= n; i++) ans += f[3][i]; cout << ans << endl; return 0; }
- 1
信息
- ID
- 630
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者