BZOJ 3907: 网格 [Catalan数 高精度]

3907: 网格

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 402  Solved: 180
[Submit][Status][Discuss]

Description

某城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m。现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点(x, y)都要满足x >= y,请问在这些前提下,到达B(n, m)有多少种走法。

Input

输入文件中仅有一行,包含两个整数n和m,表示城市街区的规模。

Output

输出文件中仅有一个整数和一个换行/回车符,表示不同的方案总数。

100%的数据中,1 <= m <= n <= 5 000

你们出题人有意思吗,变式套上高精度又一道题.....
问题在于我这个傻叉横纵坐标竟然搞混了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e4+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m;
bool notp[N];
int p[N],lp[N];
void sieve(int n){
    for(int i=2;i<=n;i++){
        if(!notp[i]) p[++p[0]]=i,lp[i]=p[0];
        for(int j=1;j<=p[0]&&i*p[j]<=n;j++){
            notp[i*p[j]]=1;
            lp[i*p[j]]=j;
            if(i%p[j]==0) break;
        }
    }
}
struct Big{
    int d[N],l;
    Big():l(1){memset(d,0,sizeof(d));d[1]=1;}
    int& operator[](int x){return d[x];}
}a,b;
void Mul(Big &a,int b){
    int g=0;
    for(int i=1;i<=a.l;i++){
        g+=a[i]*b;
        a[i]=g%10;
        g/=10;
    }
    for(;g;g/=10) a[++a.l]=g%10;
}
void Minus(Big &a,Big &b){
    for(int i=1;i<=b.l;i++){
        if(a[i]<b[i]) a[i]+=10,a[i+1]--;
        a[i]-=b[i];
    }
    int p=b.l+1;
    while(a[p]<0) a[p]+=10,a[p+1]--;
    while(a[a.l]==0) a.l--;
}
void Print(Big &a){
    for(int i=a.l;i>=1;i--) printf("%d",a[i]);
}

int e[N];
inline void add(int x,int d){
    while(x!=1){
        e[lp[x]]+=d;
        x/=p[lp[x]];
    }
}
void C(int n,int m,Big &ans){
    memset(e,0,sizeof(e));
    for(int i=n;i>=n-m+1;i--) add(i,1);
    for(int i=2;i<=m;i++) add(i,-1);
    for(int j=1;j<=p[0];j++) for(;e[j];e[j]--) Mul(ans,p[j]);
}
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    sieve(n+m);
    C(n+m,n,a);
    C(n+m,n+1,b);
    Minus(a,b);
    Print(a);
}

 

 
posted @ 2017-02-16 18:12  Candy?  阅读(330)  评论(0编辑  收藏  举报