hdu 3037 Saving Beans fzu 2020 组合 hit 2813 Garden visiting hrbeu 组合数 fzu 1564 Combination

组合数取余

P不是素数,P是素数

1)P是素数

  1. Lucas theorem 
  2. m = mk * p^k + mk-1 * p^k-1 +... +m1 * p + m0; 
  3. n = nk * p^k + nk-1 * p^k-1 +... + n1 * p + n0; 
  4. C(m,n)=C(mk,nk)*C(mk-1,nk-1)*...*C(m1,n1)*C(m0,n0); 
  5. 【题目大意】 
  6. 求C(n+m,n) % p的值。 
  7. 保证p是素数。 

C(m,n)%p=m!/(n!*(m-n)!)%p

此时使用逆元,或扩展欧几里德

2)P是任意数时

 
hdu 3037
方法一:

#include<stdio.h>
#define LL long long
#define nnum 100001
int num[nnum], x, y;
void init(int p) {
	int i;
	LL te;
	num[0] = 1;
	for (i = 1; i <= p; i++) {
		te = (LL) i;
		te = te * num[i - 1] % p;
		num[i] = (int) te;
	}
}
int modular_exp(int a, int b, int c) {
	LL res, te;
	res = 1, te = a % c;
	while (b) {
		if (b & 1) {
			res = res * te % c;
		}
		te = te * te % c;
		b >>= 1;
	}
	return (int) res;
}
int gcd(int a, int b) {
	if (a < b) {
		a ^= b, b ^= a, a ^= b;
	}
	if (b == 0) {
		return a;
	}
	return gcd(b, a % b);
}
void extend_gcd(int a, int b) {
	if (b == 0) {
		x = 1, y = 0;
		return;
	}
	extend_gcd(b, a % b);
	int tx = x;
	x = y, y = tx - a / b * y;
}
int C(int a, int b, int p) {
	if (b > a) {
		return 0;
	}
	LL te;
	te = (LL) num[b];
	te = te * num[a - b] % p;
	b = (int) te;
	a = num[a];
	int d = gcd(a, b);
	a /= d, b /= d;
	te = (LL) a;
	extend_gcd(b, p);
	x = (x % p + p) % p;
	return (int) (te * x % p);
}
void solve(LL n, LL m, int p) {
	LL ans;
	int a, b;
	ans = 1;
	while (n || m) {
		a = n % p, b = m % p;
		ans = ans * C(a, b, p) % p;
		n /= p, m /= p;
	}
	printf("%I64d\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("t.txt", "r", stdin);
#endif
	int T, p;
	LL n, m;
	while (scanf("%d", &T) != EOF) {
		while (T--) {
			scanf("%I64d %I64d %d", &n, &m, &p);
			init(p);
			solve(n + m, m, p);
		}
	}
	return 0;
}
方法二:
#include<stdio.h>
#define LL long long
#define nnum 100001
int num[nnum], x, y;
void init(int p) {
    int i;
    LL te;
    num[0] = 1;
    for (i = 1; i <= p; i++) {
        te = (LL) i;
        te = te * num[i - 1] % p;
        num[i] = (int) te;
    }
}
int modular_exp(int a, int b, int c) {
    LL res, te;
    res = 1, te = a % c;
    while (b) {
        if (b & 1) {
            res = res * te % c;
        }
        te = te * te % c;
        b >>= 1;
    }
    return (int) res;
}
int C(int a, int b, int p) {
    if (b > a) {
        return 0;
    }
    LL te;
    te = (LL) num[b];
    te = te * num[a - b] % p;
    b = te;
    te = num[a];
    return (int) (te * modular_exp(b, p - 2, p) % p);
}
void solve(LL n, LL m, int p) {
    LL ans;
    int a, b;
    ans = 1;
    while (n || m) {
        a = n % p, b = m % p;
        ans = ans * C(a, b, p) % p;
        n /= p, m /= p;
    }
    printf("%I64d\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("t.txt", "r", stdin);
#endif
    int T, p;
    LL n, m;
    while (scanf("%d", &T) != EOF) {
        while (T--) {
            scanf("%I64d %I64d %d", &n, &m, &p);
            init(p);
            solve(n + m, m, p);
        }
    }
    return 0;
} 
fzu 2020
#include<stdio.h>
#define LL long long
int modular_exp(int a, int b, int c) {
	LL res, te;
	te = a % c, res = 1;
	while (b) {
		if (b & 1) {
			res = res * te % c;
		}
		te = te * te % c;
		b >>= 1;
	}
	return (int) res;
}
int C(int n, int m, int p) {
	if (m > n) {
		return 0;
	}
	int i;
	LL res, a, b;
	res = 1, a = 1, b = 1;
	for (i = 0; i < m; i++) {
		a = a * (n - i) % p, b = b * (m - i) % p;
	}
	res = res * a * modular_exp(b, p - 2, p) % p;
	return (int) res;
}
void solve(int n, int m, int p) {
	LL ans;
	int a, b;
	ans = 1;
	while (n || m) {
		a = n % p, b = m % p;
		ans = ans * C(a, b, p) % p;
		n /= p, m /= p;
	}
	printf("%I64d\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("t.txt", "r", stdin);
#endif
	int T, m, n, p;
	while (scanf("%d", &T) != EOF) {
		while (T--) {
			scanf("%d %d %d", &n, &m, &p);
			solve(n, m, p);
		}
	}
	return 0;
}

hit 2813
 
#include<stdio.h>
#include<math.h>
#include<string.h>
#define LL long long
#define nmax 200001
int prime[nmax], flag[nmax], plen;
void init() {
	memset(flag, -1, sizeof(flag));
	int i, j;
	for (i = 2, plen = 0; i < nmax; i++) {
		if (flag[i]) {
			prime[plen++] = i;
		}
		for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
			flag[i * prime[j]] = 0;
			if ((i % prime[j]) == 0) {
				break;
			}
		}
	}
}
int modular_exp(int a, int b, int c) {
	LL res, te;
	res = 1, te = a % c;
	while (b) {
		if (b & 1) {
			res = res * te % c;
		}
		te = te * te % c;
		b >>= 1;
	}
	return res;
}
int getNum(int n, int m) {
	int res;
	res = 0;
	while (n) {
		res += n / m;
		n /= m;
	}
	return res;
}
void solve(int a, int b, int c) {
	int i, te;
	LL res;
	for (i = 0, res = 1; (i < plen) && (prime[i] <= a); i++) {
		te = getNum(a, prime[i]) - getNum(b, prime[i])
				- getNum(a - b, prime[i]);
		res = res * modular_exp(prime[i], te, c) % c;
	}
	printf("%lld\n", res);
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("t.txt", "r", stdin);
#endif
	init();
	int t, a, b, c, i;
	while (scanf("%d", &t) != EOF) {
		for (i = 1; i <= t; i++) {
			scanf("%d %d %d", &a, &b, &c);
			solve(a + b - 2, b - 1, c);
		}
	}
	return 0;
}

hrbeu 组合数

#include<stdio.h>
#include<math.h>
#include<string.h>
#define LL long long
#define nmax 100001
int prime[nmax], flag[nmax], plen;
void init() {
	memset(flag, -1, sizeof(flag));
	int i, j;
	for (i = 2, plen = 0; i < nmax; i++) {
		if (flag[i]) {
			prime[plen++] = i;
		}
		for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
			flag[i * prime[j]] = 0;
			if ((i % prime[j]) == 0) {
				break;
			}
		}
	}
}
int modular_exp(int a, int b, int c) {
	LL res, te;
	res = 1, te = a % c;
	while (b) {
		if (b & 1) {
			res = res * te % c;
		}
		te = te * te % c;
		b >>= 1;
	}
	return res;
}
int getNum(int n, int m) {
	int res;
	res = 0;
	while (n) {
		res += n / m;
		n /= m;
	}
	return res;
}
int getMin(int a, int b) {
	return (a > b ? b : a);
}
void solve(int a, int b, int c) {
	int i, te;
	LL res;
	for (i = 0, res = 1; (i < plen) && (prime[i] <= a); i++) {
		te = getNum(a, prime[i]) - getNum(b, prime[i])
				- getNum(a - b, prime[i]);
		res = res * modular_exp(prime[i], te, c) % c;
	}
	printf("%lld\n", res);
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("t.txt", "r", stdin);
#endif
	init();
	int t, a, b, c, i;
	while (scanf("%d", &t) != EOF) {
		for (i = 1; i <= t; i++) {
			scanf("%d %d %d", &a, &b, &c);
			solve(a + b, getMin(a, b), c);
		}
	}
	return 0;
}

 fzu 1564

#include<stdio.h>

#include<string.h>
#define nmax 1000001
int prime[nmax], flag[nmax], plen, mark;
void init() {
	memset(flag, -1, sizeof(flag));
	int i, j;
	for (i = 2, plen = 0; i < nmax; i++) {
		if (flag[i]) {
			prime[plen++] = i;
		}
		for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
			flag[i * prime[j]] = 0;
			if (i % prime[j] == 0) {
				break;
			}
		}
	}
}
int getNum(int n, int m) {
	int res;
	res = 0;
	while (n) {
		res += n / m;
		n /= m;
	}
	return res;
}
/*
 int getNum(int n, int m) {
 int res;
 res = 0;
 while (n) {
 res += n % m;
 n /= m;
 }
 return res;
 }
 */

void solve(int a, int b, int c) {
	int i, cnt, te;
	for (i = 0; (i < plen) && (prime[i] <= c); i++) {
		if (c % prime[i] == 0) {
			cnt = 0;
			while (c % prime[i] == 0) {
				c /= prime[i];
				cnt++;
			}
			te = getNum(a, prime[i]) - getNum(b, prime[i])
					- getNum(a - b, prime[i]);
			if (te < cnt) {
				mark = 1;
				return;
			}
			/*te = -getNum(a, prime[i]) + getNum(b, prime[i])
			 + getNum(a - b, prime[i]);
			 if (te / (prime[i] - 1) < cnt) {
			 mark = 1;
			 return;
			 }*/
		}
	}
	if (mark && (c > 1)) {
		te = getNum(a, prime[i]) - getNum(b, prime[i])
				- getNum(a - b, prime[i]);
		if (te < cnt) {
			mark = 1;
			return;
		}
		/*te = -getNum(a, c) + getNum(b, c) + getNum(a - b, c);
		 if (te / (c - 1) < cnt) {
		 mark = 1;
		 return;
		 }*/
	}
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("t.txt", "r", stdin);
#endif
	int t, a, b, c;
	init();
	while (scanf("%d", &t) != EOF) {
		while (t--) {
			scanf("%d %d %d", &a, &b, &c);
			mark = 0;
			solve(a, b, c);
			if (mark) {
				puts("No");
			} else {
				puts("Yes");
			}
		}
	}
	return 0;
}

原文地址:https://www.cnblogs.com/xiaoxian1369/p/2147122.html