$题目描述:请你在一个长度为 的数字序列中找到长度为$
$的严格上升子序列的个数(注意不是子串),答案对1e^9 + 7取模。$
$输入格式$
$第一行输入数据组数T 。$
$接下来有2T行,其中每2行表示如下:$
$第一行输入两个数n,m表示序列的长度和需要找到的严格上升子序列的长度。$
$第二行n个数,表示给定的数列。$
$输出格式$
$输出T行,设 表示第i个数据得出的答案,则输出格式为 Case #i: ans。$
样例输入:
2
3 2
1 2 3
3 2
3 2 1
样例输出
Case #1: 3
Case #2: 0
$代码呈现:$
#include <bits/stdc++.h>
using namespace std;
long long T, t, tot;
long long n, m;
long long a[100010], f[2010][2010], q[20010];
long long p = 1e9 + 7;
long long c[2010][2010];
void lsh() {
for (long long i = 1; i <= n; i++) q[i] = a[i];
sort(q + 1, q + 1 + n);
tot = unique(q + 1, q + 1 + n) - 1 - q;
for (long long i = 1; i <= n; i++) a[i] = lower_bound(q + 1, q + 1 + tot, a[i]) - q;
}
long long lowbit(long long x) { return x & (-x); }
void add(long long i, long long x, long long y) {
for (; x <= tot; x += lowbit(x)) (c[i][x] += y) % p;
}
long long sum(long long i, long long x) {
long long ans = 0;
for (; x; x -= lowbit(x)) (ans += c[i][x]) % p;
return ans;
}
int main() {
scanf("%lld", &T);
while (T--) {
t++;
scanf("%lld%lld", &n, &m);
for (long long i = 1; i <= n; i++) scanf("%lld", &a[i]);
lsh();
for (long long i = 1; i <= n; i++) {
for (long long j = 1; j <= m; j++) {
if (j == 1)
f[i][j] = 1;
else
f[i][j] = sum(j - 1, a[i] - 1) % p;
add(j, a[i], f[i][j]);
}
}
long long ans = 0;
for (long long i = m; i <= n; i++) ans = (ans + f[i][m]) % p;
printf("Case #%lld: %lld\n", t, ans);
memset(f, 0, sizeof(f));
memset(c, 0, sizeof(c));
}
return 0;
}