BZOJ3907 grid

Cat thought this thing was made to take a combination of mathematics.

This need will first do the Cat $ C_ {2n} ^ n-C_ {2n} ^ {n-1} $ analysis is how to fold line or grid method.

Grid method: Without limitation, the number of programs from (0,0) to (n, n) is $ C_ {2n} ^ n $, is a total of 2n operations position (right or up), we put up these operations take a position that was inserted into the above formula, the yellow line is above the first line when we come to unlawfully encountered, then we will eventually come to (n, n) at this point, if we rectangular folded along this line, we encounter the yellow line, and then went to (n, n) and the walk, you can be mapped to touch the yellow line, and then went to (n-1, n + 1) and the walk because of symmetry thing.

And we met before the yellow line moves in the folding matrix is not affected, so that the number of illegal schemes that from (0,0) went to (n-1, n + 1 ) number of programs, this and almost above analysis, a total of $ C_ {2n} ^ {n -1} $ species minus all illegal, is legal, $ {C_-C_ 2N} ^ {n-2N-n-} ^ {}. 1 $ .

Fold line: that is, from (0,0) to (2n, 0), each time only along the y = x or y = -x down one unit, the entire image is not the last program number portion located below the x. Without limitation, then the total number of programs for $ C_ {2n ^ n} $ , since folding line can split into 2n segments, then there are n pieces rise, fall n stages. Can not cross the x-axis, from the first encounter of this line y = -1 is not a legitimate start, and after this point we have y = -1 folded along the fold lines, since the last arrival (2n, 0) points, Total off after reaching the (2n, -2), is transformed into the case (0,0) to (2n -2,) the number of programs, there are n stages, n-1 up period, n + 1 segments down, the program number $} ^ {C_ {2N-n-$}. 1 , all minus unlawful, is legal, $ {C_-C_ 2N} ^ {n-2N-n-} ^ {} $. 1 .

That this question is much simpler, with the above same method as above, to replace a n m on the same subject

答案就是$C_{n+m}^n-C_{n+m}^{m-1}$,下面的代码是化简后的式子,没有高精减,高精除用唯一分解刚过去,而且时间复杂度也还好,就打的n√n的拆分,nlogn的拆分在下一篇博客里,(因为那个题√n拆过不去QAQ)。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
int n,m;
int prime[5000],prime_num;
bool v[10050];
int fz[5000],fm[5000];
struct Bigint{
    int a[90000],len;
    void clear(){
        memset(a,0,sizeof(a));
        a[1]=1;
        len=1;
    }
    friend void operator * (Bigint &x,int y){
        int delta=0;
        for(int i=1;i<=x.len;i++){
            x.a[i]=x.a[i]*y+delta;
            delta=x.a[i]/10;
            x.a[i]%=10;
        }
        while(delta>0){
            x.a[++x.len]=delta%10;
            delta/=10;
        }
        while(x.a[x.len]==0&&x.len>1)
            x.len--;
    }
    void out(){
        for(int i=len;i>=1;i--)
            printf("%d",a[i]);
    }
}ans;
void doprime(){
    for(int i=2;i<=10005;i++){
        if(!v[i]) prime[++prime_num]=i;
        for(int j=1;j<=prime_num&&i*prime[j]<=10005;j++){
            v[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
void mulfz(int x){
    for(int i=1;i<=prime_num;i++)
        while(x%prime[i]==0){
            fz[i]++;
            x/=prime[i];
        }
}
void mulfm(int x){
    for(int i=1;i<=prime_num;i++)
        while(x%prime[i]==0){
            fm[i]++;
            x/=prime[i];
        }
}
int main(){
    scanf("%d%d",&n,&m);
    doprime();ans.clear();
    for(int i=2;i<=n+m;i++)
        mulfz(i);
    mulfz(n-m+1);
    for(int i=2;i<=m;i++)
        mulfm(i);
    for(int i=2;i<=n+1;i++)
        mulfm(i);
    /*for(int i=1;i<=prime_num;i++)
        cout<<prime[i]<<" ";cout<<endl;*/
    for(int i=1;i<=prime_num;i++){
        for(int j=1;j<=fz[i]-fm[i];j++)
            ans*prime[i];
    }
    ans.out();
    puts("");
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Yu-shi/p/11222174.html