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

  • 相关阅读:
    RedHat 更新CentOS Yum源(转)
    ubuntu 印象笔记
    (转)FFMPEG filter使用实例(实现视频缩放,裁剪,水印等)
    (转)学习ffmpeg官方示例transcoding.c遇到的问题和解决方法
    源码调用ffmpeg库时,需要注意接口为C接口
    codeforces 722D Generating Sets 【优先队列】
    poj2970 The lazy programmer 【优先队列】
    codeblocks17.12 不能启动调试器
    Unity动画知识之二:Animator动画状态机
    关于unity里pbr技术和材质 unity5默认shader和传统的对比
  • 原文地址:https://www.cnblogs.com/BobHuang/p/9761160.html
Copyright © 2011-2022 走看看