• CodeForces


    Sereja is interested in intervals of numbers, so he has prepared a problem about intervals for you. An interval of numbers is a pair of integers [l, r] (1 ≤ l ≤ r ≤ m). Interval [l1, r1] belongs to interval [l2, r2] if the following condition is met: l2 ≤ l1 ≤ r1 ≤ r2.

    Sereja wants to write out a sequence of n intervals [l1, r1], [l2, r2], ..., [ln, rn] on a piece of paper. At that, no interval in the sequence can belong to some other interval of the sequence. Also, Sereja loves number x very much and he wants some (at least one) interval in the sequence to have li = x. Sereja wonders, how many distinct ways to write such intervals are there?

    Help Sereja and find the required number of ways modulo 1000000007 (109 + 7).

    Two ways are considered distinct if there is such j (1 ≤ j ≤ n), that the j-th intervals in two corresponding sequences are not equal.


    Input

    The first line contains integers n, m, x (1 ≤ n·m ≤ 100000, 1 ≤ x ≤ m) — the number of segments in the sequence, the constraints on the numbers in segments and Sereja's favourite number.

    Output

    In a single line print the answer modulo 1000000007 (109 + 7).

    Examples
    Input
    1 1 1
    Output
    1
    Input
    3 5 1
    Output
    240
    Input
    2 3 3
    Output
    6
    Note

    In third example next sequences will be correct: {[1, 1], [3, 3]}, {[1, 2], [3, 3]}, {[2, 2], [3, 3]}, {[3, 3], [1, 1]}, {[3, 3], [2, 2]}, {[3, 3], [1, 2]}.

    题意:给定长度为M的数轴,让你选择N个带编号的线段,使得没有线段有包含关系。 给定X,让你至少选择了一个左端点为X的线段。

    思路:N<=M;  所以N<sqrt(N*M)<=330; 没有包含关系,那么线段A的左端点大于B的左端点,那么A的右端点也一定大于B的右端点。所以我们可以自己去匹配。只保存当点左端点和右端点个数即可。

    用dp[i][j][x]表示前x个点选择了i个左端点,j个右端点,不难得到方程。由于x可能有点大,我们用滚动数组。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=330;
    const int Mod=1e9+7;
    int dp[maxn][maxn][2];
    int main()
    {
        int N,M,X;
        scanf("%d%d%d",&N,&M,&X);
        if(N>M) return puts("0"),0;
        dp[0][0][0]=1;
        rep(k,1,M){//位置
          rep(i,0,min(N,M)){ //左括号
            rep(j,0,i){ //右括号
                int p=k&1;
                if(k==X){
                    dp[i][j][p]=0;
                    if(i>j) (dp[i][j][p]+=dp[i-1][j][p^1])%=Mod; //
                    if(i&&j) (dp[i][j][p]+=dp[i-1][j-1][p^1])%=Mod;//左+右
                }
                else {
                    dp[i][j][p]=dp[i][j][p^1]; //不放
                    if(i>j) (dp[i][j][p]+=dp[i-1][j][p^1])%=Mod; //
                    if(i&&j) (dp[i][j][p]+=dp[i-1][j-1][p^1])%=Mod;//左+右
                    if(j) (dp[i][j][p]+=dp[i][j-1][p^1])%=Mod;//
                }
            }
          }
        }
        rep(i,1,N) dp[N][N][M&1]=1LL*dp[N][N][M&1]*i%Mod;
        printf("%d
    ",dp[N][N][M&1]);
        return 0;
    }
  • 相关阅读:
    在C++里while语句的一个妙用
    看书——我和村上作品
    Linux下使用QQ和查看QQ空间
    Redflag 6.0 Linux下装 nvidia fx5200显卡驱动
    唇伤
    看书——我和村上作品
    Firefox 3 查看QQ空间的问题——只能开8位以下QQ的空间
    codeforces 315 B.Sereja and Array
    codeforces 285C Building Permutation
    省赛总结
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10149481.html
Copyright © 2020-2023  润新知