P1492 猩猩散步
题目描述
猩猩,骆驼,还有泡泡经常喜欢在饭后到操场上散步,由于猩猩的走路姿势最突出最显眼,理所应当的成为他们中的主角,所以我的题目就说猩猩散步了。(骆驼和泡泡别有意见哈,和猩猩争啥……)
当然,话说回来,猩猩在OI上的能力也是不容低估的,你看,散步时还会想一道与此相关的问题,这是道经典的不能再经典的问题了。
在一个m×n的矩阵上,猩猩在左下角的顶点出现了,他只能沿着路径向上或者向右走,他的目标是“蠕动”到右上角的顶点,问他有多少路径可以选择。嗯,这个、这个、这个似乎地球人都知道怎么做,但是请注意,我有个条件没给呢!m和n现在的最大范围是50000,这可怎么办?仔细想想吧。
输入格式
只有一行,包含两个整数m和n,其上限均为50000
输出格式
由于最后的答案数目过大,所以只检查后100位,输出时每行十个数字,没空格间隔,共十行,如果答案位数没超过100位,则需要在空位上补0。
输入输出样例
输入 #1
7 4
输出 #1
0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000330
说明/提示
各个测试点3s
思路
求组合数C(min(n,m),n+m)
需要高精
朴素高精过不了,跑得非常非常慢
需要优化
设ans为n与m之和
我们把1-ans中的每一个素数筛出来
然后利用素数乘
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000010;
bool ss[N];
long long x,k;
int a[N],p[N];
long long ans=1,s=0,l=0;
void mu(int q) {
for(int i=1; i<=l; i++)
p[i]=p[i]*q;
int i=1;
while(i<=l||p[i]>10) {
p[i+1]=p[i+1]+p[i]/10;
p[i]=p[i]%10;
i++;
}
l=i;
while(p[l]==0)
l--;
}
void mul(int q) {
for(int i=1; i<=sqrt(q)+1; i++)
if(ss[i])
while(q%i==0) {
a[i]++;
q=q/i;
}
if(q>0)
a[q]++;
}
void d(int q) {
for(int i=1; i<=sqrt(q)+1; i++)
if(ss[i])
while(q%i==0) {
a[i]--;
q=q/i;
}
if(p>0)
a[q]--;
}
int main () {
p[1]=1;
l=1;
scanf("%d%d",&k,&x);
ans=k+x;
for(int i=2; i<=ans; i++)
ss[i]=true;
for(int i=2; i<=ans; i++)
if (ss[i])
for(int j=i; j<=ans/i; j++)
ss[i*j]=false;
for(int i=1; i<=min(k,x); i++)
mul(ans-i+1);
for(int i=1; i<=min(k,x); i++)
d(i);
for(int i=1; i<=ans; i++)
for (int j=1; j<=a[i]; j++)
mu(i);
for(int i=100; i>=1; i--)
if (i%10!=1)
printf("%d",p[i]);
else
printf("%d\n",p[i]);
return 0;
}

浙公网安备 33010602011771号