您的位置:首页 > 其它

【BZOJ】【3907】网格

2015-03-20 18:26 239 查看

组合数学/python

3907: 网格

Time Limit: 1 Sec Memory Limit: 256 MB
Submit: 162 Solved: 76
[Submit][Status][Discuss]

Description


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

/**************************************************************
Problem: 3907
User: Tunix
Language: C++
Result: Accepted
Time:84 ms
Memory:944 kb
****************************************************************/

#include<cstdio>
#include<cstring>

typedef long long LL;

const int N=10001;
const LL mod=100000000;

int tot=0,x
,p
,v
={0};
LL a[1000],b[1000];

LL pow(LL x,int p) {
LL t=1;for (;p;p>>=1,x*=x) if (p&1) t*=x;return t;
}

void mul(LL a[],LL y) {
LL x=0,&l=a[0];
for (int i=1;i<=l;i++) {
a[i]=a[i]*y+x;
x=a[i]/mod;
a[i]%=mod;
}
while (x) a[++l]=x%mod,x/=mod;
}

void dec(LL a[],LL b[]) {
LL &l=a[0];
for (int i=1;i<=l;i++) {
if (a[i]<b[i]) a[i+1]--,a[i]+=mod;
a[i]-=b[i];
}
while (!a[l]) l--;
}

void getc(LL a[],int n,int m) {
memset(x,0,sizeof x);
for (int i=2;i<=n;i++) x[i]++;
for (int i=2;i<=m;i++) x[i]--;
for (int i=2;i<=n-m;i++) x[i]--;
for (int i=n;i>=2;i--)
if (!v[i]) mul(a,pow(i,x[i]));
else x[v[i]]+=x[i],x[i/v[i]]+=x[i];
}

void print(LL a[]) {
int l=a[0];
printf("%lld",a[l]);
for (int i=l-1;i>=1;i--) printf("%08lld",a[i]);
printf("\n");
}

int main() {
int n,m;
scanf("%d%d",&n,&m);
for (int i=2;i<=n+m;i++) {
if (!v[i]) p[++tot]=i;
for (int j=1,k;j<=tot,(k=p[j]*i)<=n+m;j++) {
v[k]=p[j];
if (i%p[j]==0) break;
}
}
a[0]=a[1]=b[0]=b[1]=1;
getc(a,n+m,n);
getc(b,n+m,n+1);
dec(a,b);
print(a);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: