Skip to content

14193: 【原4193】isn

题目

题目描述

author: Sakiko 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4193

Description

给出一个长度为 \(n\) 的序列\(A \ (A_1, A_2, ..., A_n) \) 。如果序列 \(A\) 不是非降的,你必须从中删去一个数,重复这一操作,直到 \(A\) 非降为止。求有多少种不同的操作方案,答案模 \(10^9 + 7 \) 。

Input Format

第一行一个整数 \(T\) , 代表数据组数。
对于每组数据,第一行一个整数 \(n\) 。
接下来一行 \(n\) 个整数,描述 \(A\) 。

Output Format

\(T\) 行,每行一个整数,描述答案。

Sample Input

1
4
1 7 5 3

Sample Output

18

Data Range

对于10%的数据,\(1<=n<=10\)。
对于30%的数据,\(1<=n<=20\)。
对于50%的数据,\(1<=n<=50\)。
对于70%的数据,\(1<=n<=200\)。
对于100%的数据,\(1<=n<=2000, T<=5\)。

zqy2018's solution

/*
    See the solution at https://github.com/zqy1018/sjtu_oj_solutions/blob/master/solutions/sjtu4193.md
*/
#include <bits/stdc++.h>
#define INF 2000000000
#define M 1000000007
using namespace std;
typedef long long ll;
int read(){
    int f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
    while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
    return f * x; 
}
int fac[2005];
int n, a[2005];
int f[2005][2005], tot;
int c[2005], l[2005];
pair<int, int> b[2005];
inline int lowbit(int x){
    return x & (-x);
}
inline int modadd(int x, int y){
    return (x + y >= M ? x + y - M: x + y);
}
void add(int r, int x){
    while (r <= n)
        c[r] = modadd(c[r], x), r += lowbit(r);
}
int query(int r){
    int res = 0;
    while (r > 0)
        res = modadd(res, c[r]), r -= lowbit(r);
    return res;
}
void init(){
    n = read();
    for (int i = 1; i <= n; ++i)
        a[i] = read(), b[i] = make_pair(a[i], i);
    sort(b + 1, b + n + 1);
}
void solve(){
    memset(f, 0, sizeof(f));
    memset(l, 0, sizeof(l));
    l[1] = n;
    for (int i = 1; i <= n; ++i)
        f[i][1] = 1;
    for (int j = 2; j <= n; ++j){
        for (int i = 0; i <= n; ++i)
            c[i] = 0;
        for (int i = 1; i <= n; ++i){
            int pos = b[i].second;
            f[pos][j] = query(pos - 1);
            add(pos, f[pos][j - 1]);
        }
        for (int i = j; i <= n; ++i)
            l[j] = modadd(l[j], f[i][j]);
    }
    int ans = l[n];
    for (int i = n - 1; i >= 1; --i){
        int t = 1ll * l[i] * fac[n - i] % M;
        t = modadd(t, M - 1ll * (1ll * l[i + 1] * fac[n - i - 1] % M) * (i + 1) % M);
        ans = modadd(ans, t);
    }
    printf("%d\n", ans);
}
int main(){
    int T = read();
    fac[0] = fac[1] = 1;
    for (int i = 2; i <= 2000; ++i)
        fac[i] = 1ll * fac[i - 1] * i % M;
    while (T--){
        init();
        solve();
    }
    return 0;
}