关于DevC++的计算错误(?)
  • 板块学术版
  • 楼主Starlight237
  • 当前回复6
  • 已保存回复6
  • 发布时间2021/3/7 21:35
  • 上次更新2023/11/5 02:19:11
查看原帖
关于DevC++的计算错误(?)
75765
Starlight237楼主2021/3/7 21:35

输入4824452825608873 735137 688586(有文件读写)

代码中注释部分会出bug,运行代码得知,当 prod 变量为0时,pd=-233345,i+n=1961286755,pk=1123280. 而prod=pd*(i+n)%pk,经计算器检验正确的prod=-503635显然不为0,单独写代码计算-233345*1961286755LL%1123280也不为0,但是计算pd*(i+n)%pk时结果总是0。

显然因为n是longlong,所以算式计算时会自动强转成longlong,应该不存在溢出的问题(

#include<bits/stdc++.h>
using namespace std;
#define reg register
#define ll long long
extern "C" {
	namespace io {
#define BUFS 100000
		static char in[BUFS], *p = in, *pp = in;
#define gc (p == pp && (pp = (p = in) + fread(in, 1, BUFS, stdin), p == pp) ? EOF : *p++)
		inline ll read() {
			reg ll x = 0; reg char ch, f = 0;
			while (!isdigit(ch = gc)) f |= ch == '-';
			while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc;
			return f ? -x : x;
		}
	}
}
#define rd io :: read
ll m, n;
int p, fac[1001], pw[1001], e, A[1001], B[1001];
inline int qpow(int a, ll b, int mod) {
	reg int res = 1;
	for (; b; b >>= 1, a = (ll)a * a % mod) (b & 1) && (res = (ll)res * a % mod);
	return res;
}
int exgcd(int&x, int&y, int a, int b) {
	if (b == 0) {
		x = 1, y = 0;
		return a;
	}
	int g = exgcd(x, y, b, a % b), t = x;
	x = y, y = t - a / b * y;
	return g;
}
inline int inv(int a, int mod) {
	int x, y;
	exgcd(x, y, a, mod);
	return x;
}
inline int calc(ll n, int p, int pk) {
	if (!n) return 1;
	reg int rho = pk, prod = 1;
	for (reg int i = 1; i <= pk; ++i)
		if (i % p) prod = (ll)prod * i % pk;
	prod = qpow(prod, n / pk, pk);
	for (reg int i = pk * (n / pk) + 1 - n, pd; i <= 0; ++i)
		if ((i+n) % p) pd=prod,prod = pd * (i + n) % pk, prod || (printf("%d %d %d", pd, i+n,pk), fclose(stdin), freopen("con", "r", stdin), getchar(),0);//就是这里
	return (ll)calc(n / p, p, pk) * prod % pk;
}
inline ll g(ll n, int p) {
	if (n < p) return 0;
	return n / p + g(n / p, p);
}
inline int cal(ll n, ll m, int p, int pk) {
	int f1 = calc(n, p, pk), f2 = inv(calc(m, p, pk), pk), f3 = inv(calc(n - m, p, pk), pk);
	int G = qpow(p, g(n, p) - g(m, p) - g(n - m, p), pk);
	return (ll)f1 * f2 % pk * f3 % pk * G % pk;
}
int main() {
	freopen("2.in", "r", stdin);
	n = rd(), m = rd(), p = rd();
	reg int tmp = p;
	for (reg int i = 2, j = sqrt(p), d = 0; i <= j; ++i) {
		if (!tmp) break;
		if (tmp % i == 0) {
			fac[++e] = i;
			d = 1;
			do
				tmp /= i, d *= i;
			while (tmp % i == 0);
			pw[e] = d;
		}
	}
	if (tmp > 1) ++e, fac[e] = pw[e] = tmp;
	for (reg int i = 1, P, PK; i <= e; ++i)
		P = fac[i], PK = pw[i],
		A[i] = cal(n, m, P, PK),
		B[i] = PK;
	reg int ans = 0;
	for (reg int i = 1, M, T; i <= e; ++i)
		M = p / B[i], T = inv(M, B[i]),
		ans = (ans + (ll) A[i] * M % p * T % p + p) % p;
	printf("%d", ans);
	return 0;
}
2021/3/7 21:35
加载中...