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)两条路径

  • 相关阅读:
    2019 web安全基础知识学习
    nc语法和nc木马远程控制主机
    公钥、私钥、hash、数字签名、CA以及验证过程
    A5/1流加密理解和算法实现
    TCP/IP和OSI/RM以及协议端口
    【转】TCP/IP网络协议各层首部
    校园网 虚拟机VMware Linux桥接模式 无法上网 问题
    本地远程查看服务器tomcat 上虚拟机信息
    跨域访问的解决
    混合调用tk.mybatis.mapper 与 自编xml文件 的配置
  • 原文地址:https://www.cnblogs.com/BobHuang/p/9761160.html
Copyright © 2011-2022 走看看