intgauss() { int c, r; for(c = 0, r = 0; c < n; c ++) //找到当前列中绝对值最大的一行,本题中最大值即是1 { int t = r; for(int i = r; i < n; i ++) if(a[i][c]) t = i; if(!a[t][c]) continue; for(int i = c; i <= n; i ++) swap(a[r][i], a[t][i]); //把这一行换到最上面 for(int i = r + 1; i < n; i ++) if(a[i][c]) for(int j = n; j >= c; j --) a[i][j] ^= a[r][j]; r ++; } if(r < n) { for(int i = r; i < n; i ++) if(a[i][n]) //0 等于 非0 return2; //无解 return1; //有多解 } for(int i = n - 1; i >= 0; i --) //有唯一解,倒着计算出来 for(int j = i + 1; j < n; j ++) a[i][n] ^= a[i][j] * a[j][n]; return0; }
intmain() { cin >> n; for(int i = 0; i < n; i ++) for(int j = 0; j < n + 1; j ++) cin >> a[i][j]; int res = gauss(); if(res == 0) for(int i = 0; i < n; i ++) cout << a[i][n] << endl; elseif(res == 1) puts("Multiple sets of solutions"); elseputs("No solution"); return0; }
求组合数
求组合数I(Acwing 885):
给定n组询问,每组询问给定两个整数$a,b$,请你输出$C^b_a\, mod \, (10^9+7)$的值。
intqmi(int a, int k)//快速幂,利用快速幂求逆元 { int res = 1; while(k) { if( k & 1) res = (LL) res * a % p; //计算a! / (a - b)! (mod p) a = (LL) a * a % p; ////计算 1 / b! (mod p) k >>= 1; } return res; }
intC(int a, int b)//计算C_a^b { int res = 1; for(int i = 1, j = a; i <= b; i++, j--) { res = (LL) res * j % p; res = (LL) res * qmi(i, p - 2) % p; } return res; }
intlucas(LL a, LL b) { if(a < p && b < p) return C(a, b); return (LL) C(a % p, b % p) * lucas(a / p, b / p) % p; }
intmain() { int n; cin >> n; while(n--) { LL a, b; //注意这里要用LL 存a, b,数据范围是1到10^18 cin >> a >> b >> p; cout << lucas(a, b) << endl; } return0; }
intget(int a, int p)//求a分解质因数后,a!中p的指数 { int res = 0; while (a) { res += a / p; a /= p; } return res; }
vector<int> mul(vector<int> a, int b) //高精度乘法,一个很大的数,乘一个较小的数 { vector<int> c; int t = 0; for(int i = 0; i < a.size(); i ++) { t += a[i] * b; c.push_back(t % 10); t /= 10; } while (t) { c.push_back(t % 10); t /= 10; } return c; //这里不需要处理前导0,因为本题中不会乘0 }
intmain() { int a, b; cin >> a >> b; get_primes(a); //求a的质因数 for(int i = 0; i < cnt; i ++) { int p = primes[i]; sum[i] = get(a, p) - get(a - b, p) - get(b, p); } vector<int> res; res.push_back(1); for(int i = 0; i < cnt; i ++) for(int j = 0; j < sum[i]; j ++) res = mul(res, primes[i]); for(int i = res.size() - 1; i >= 0; i --) printf("%d", res[i]); puts(""); return0; }
//用快速幂求逆元,这里的mod是质数;若mod不是质数,只能用扩展欧几里得算法求逆元 intqmi(int a, int k, int p) { int res = 1; while(k) { if(k & 1) res = (LL) res * a % p; a = (LL) a * a % p; k >>= 1; } return res; } intmain() { int n; cin >> n; int a = 2 * n, b = n; int res = 1; //用下面两个循环计算C_2n^n for(int i = a; i > a - b; i --) res = (LL)res * i % mod; for(int i = 1; i <= b; i ++) res = (LL) res * qmi(i, mod - 2, mod) % mod; res = (LL) res * qmi(n + 1, mod - 2, mod) % mod; //乘 1/ (n + 1) cout << res << endl; return0; }