BZOJ3907 сетки

Кошка подумал, что это дело было сделано, чтобы принять сочетание математики.

Эта потребность будет первым сделать Cat $ C_ {2n} ^ п-C_ {2n} ^ {п-1} $ анализа как линии сгиба или метод сеток.

Метод сетки: Без ограничений, количество программ от (0,0) до (п, п) $ C_ {2n} ^ N $, в общей сложности 2n позиции операций (вправо или вверх), мы миримся эти операции занимают положение, которое было вставлено в приведенной выше формуле, желтая линия находится выше первой линии, когда мы приходим к незаконно встречается, то мы в конечном итоге прийти к (п, п) в этой точке, если мы прямоугольный складывают вдоль этой линии, мы сталкиваемся с желтой линией, а затем пошли к (п, п) и прогулкам, вы можете быть сопоставлены прикоснуться к желтой линии, а затем пошли к (п-1, п + 1) и прогулка из-за симметрии вещи.

И мы встретились перед желтая линия движется в матрице складывания не влияет, так что число незаконных схем, из (0,0) пошли к (п-1, п + 1 ) число программ, это и почти выше анализа, в общей сложности $ C_ {2n} ^ {п -1} $ видов минус все незаконно, является законным, $ {C_-C_ 2N} ^ {п-2-N-н-} ^ {}. 1 $ .

Линии сгиба: то есть, из (0,0) до (2n, 0), каждый раз только вдоль у = х или у = -x вниз на одну единицу, все изображение не число часть последней программы расположена ниже оси х. Без ограничений, то общее число программ для $ C_ {2n ^ п} $ , так как линии сгиба можно разделить на 2n отрезков, то существуют п штук поднимаются, падают п этапов. Не может пересекать ось х, от первой встречи этой линии у = -1 не является законным начало, и после этого момента мы имеем у = -1 складывают вдоль линий сгиба, с момента последнего прибытия (2n, 0) очков, Всего выключение после достижения (2n, -2), преобразуется в случае (0,0) до (2n -2,) число программ, есть N этапы, п-1 до периода, п + 1 сегменты вниз, программа номер $} ^ {C_ {2N-н- $}. 1 , все минус незаконным, является законным, $ {C_-C_ 2N} ^ {п-2-N-н-} ^ {} $. 1 .

Именно этот вопрос гораздо проще, с выше таким же способом, как описано выше, чтобы заменить п т на ту же тему

答案就是$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

 

рекомендация

отwww.cnblogs.com/Yu-shi/p/11222174.html