题目:http://61.187.179.132:8080/JudgeOnline/status
题目大意:由n个1,m个零组成的字符串,要求对于任意位置k都有前k个字符中1的个数大于等于0的个数。(1 <= m <= n <= 1000000) 最后输出结果MOD 20100403
考点:C(n,m) mod p (其中n,m很大, p不大)
思路:题目可转化为从矩阵中(0,0)点走到(n,m)点的路径总数减去从(1,-1)点走到(n,m)的路径总数。(规定向上走为1,向下走为0),然后利用组合取模求解
提交情况:wrong answer 6次
Time limit error 4 次 原因 数组开小了,应该是n +m的大小, 我开成了n
经验: 注意数组含义,定义适当大小的数组。
收获: 阶乘中素因子的个数
AC code:
#include <stdio.h>
#include <string.h>
#define MAXN 2000100
#define P 20100403
#define I64 __int64
inta[MAXN], boo[MAXN];
I64 prime[MAXN], count;
voidGet_Prime(I64 n){
I64 i, j;
count = 0;
memset(boo, 0, sizeof(boo));
for(i = 2; i <= n; i ++){
if(!boo[i]) prime[count ++] = i;
for(j = 0; j < count; j ++){
if(prime[j] * i > n) break;
boo[prime[j] * i] = 1;
if(i % prime[j] == 0) break;
}
}
}
voidget_factor(I64 n, I64 m){
I64 i, data1, data2, data3;
memset(a, 0, sizeof(a));
for(i = 0; i < count; i ++){
data1 = n, data2 = m, data3 = n - m;
while(data1 || data2 || data3){
a[i] += data1/prime[i] - data2/prime[i] - data3/prime[i];
data1 /= prime[i];
data2 /= prime[i];
data3 /= prime[i];
}
}
}
I64 multi(I64 x, I64 y){
I64 ans = 0;
while(y){
if(y & 1) ans = (ans + x) % P;
x = (x + x) % P;
y >>= 1;
}
return ans;
}
I64 POWER(I64 x, I64 y){
I64 ans = 1;
while(y){
if(y & 1) ans = multi(ans, x);
x = multi(x, x);
y >>= 1;
}
return ans;
}
I64 Get_combination(I64 n, I64 m){
I64 i, ans = 1;
get_factor(n, m);
for(i = 0; i < count; i ++)
ans = multi(ans, POWER(prime[i], a[i]));
return ans;
}
int main(){
I64 n, m;
while(~scanf("%I64d %I64d", &n, &m)){
Get_Prime(n + m);
I64 ans1 = Get_combination(n + m, n);
I64 ans2 = Get_combination(n + m, n + 1);
printf("%I64d\n", (ans1 + P - ans2) % P);
}
return 0;
}