zoukankan      html  css  js  c++  java
  • HDU5852 Intersection is not allowed!

    拖了100年的题目

    There are K pieces on the chessboard. 

    The size of the chessboard is N*N. 

    The pieces are initially placed on the top cells of the board. 

    A piece located on (r, c) can be moved by one cell right to (r, c + 1) or one cell down to (r+1, c). 

    Your task is to count how many different ways to move all pieces to the given positions at the bottom of the board. 

    Furthermore, the paths of the pieces mustn’t intersect each other. 

    InputThe first line of input contains an integer T-the number of test cases. 

    Each test case begins with a line containing two integers-N(1<=N<=100000) and K(1<=K<=100) representing the size of the chessboard and the number of pieces respectively. 

    The second line contains K integers: 1<=a1<a2< …<aK<=N representing the initial positions of the pieces. That is, the pieces are located at (1, a1), (1, a2), …, (1, aK). 

    Next line contains K integers: 1<=b1<b2<…<bK<=N representing the final positions of the pieces. This means the pieces should be moved to (N, b1), (N, b2), …, (N, bK). 
    OutputPrint consecutive T lines, each of which represents the number of different ways modulo 1000000007.Sample Input

    1
    5 2
    1 2
    3 4

    Sample Output

    50

    这个题目一看到还是晕了,但是每个点好像很有规律的啊,可以容斥的

    LGV了解一下

    然后就是处理出行列式,计算行列式的值了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll MD=1e9+7;
    const int N=2e5+5,M=105;
    int s[M],e[M];
    ll a[M][M];
    ll det(int n)
    {
        ll ans=1;
        int sign=0;
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                int x=i,y=j;
                while(a[y][i])
                {
                    ll t=a[x][i]/a[y][i];
                    for(int k=i; k<n; k++)
                        a[x][k]=(a[x][k]-a[y][k]*t)%MD;
                    swap(x,y);
                }
                if(x!=i)
                {
                    for(int k=0; k<n; k++)swap(a[i][k],a[x][k]);
                    sign^=1;
                }
            }
            if(a[i][i]==0)return 0;
            else ans=ans*a[i][i]%MD;
    
        }
        if(sign)ans=-ans;
        ans=(ans+MD)%MD;
        return ans;
    }
    int fac[N],inv[N];
    ll C(ll n,ll m)
    {
        if(m<0)return 0;
        return 1LL*fac[n]*inv[m]%MD*inv[n-m]%MD;
    }
    int main()
    {
        inv[0]=inv[1]=fac[0]=fac[1]=1;
        for(int i=2; i<N; i++) fac[i]=1LL*fac[i-1]*i%MD,inv[i]=1LL*inv[MD%i]*(MD-MD/i)%MD;
        for(int i=2; i<N; i++) inv[i]=1LL*inv[i-1]*inv[i]%MD;
        int n,k,t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&k);
            for(int i=0; i<k; i++)scanf("%d",&s[i]);
            for(int i=0; i<k; i++)scanf("%d",&e[i]);
            for(int i=0; i<k; i++)
                for(int j=0; j<k; j++)a[i][j]=C(n-1+e[j]-s[i],e[j]-s[i]);
            printf("%lld
    ",det(k));
        }
    }

    从(1,1)到(n,m)两条互不相交的路径条数C(n+m-4, n-2)^2-C(n+m-4,n-1)^2

    简化为从(1,2)到(n-1,m)从(2,1)到(n,m-1)两条路径

  • 相关阅读:
    jmeter压测-05-xpath表达式
    测试那些事-测试资源篇
    测试那些事-沟通篇
    测试那些事-前端
    测试那些事儿-后端
    记一次大数据量不同处理方式下服务器负载
    jmeter压测dubbo接口,参数为dto时如何写传参及有错误时的分析思路
    pyton3 字典排序
    python测试dubbo接口
    记录一下telnet测试dubbo接口,参数为dto时怎么测试,枚举类型传参
  • 原文地址:https://www.cnblogs.com/BobHuang/p/9761160.html
Copyright © 2011-2022 走看看