luogu2312 解方程
题目大意
已知多项式方程:a0+a1x+a2x^2+..+anx^n=0求这个方程在[1, m ] 内的整数解(n 和m 均为正整数)ai<=10^10000
题解
枚举多个不太大的质数$p_i$,枚举$x\in[0,p_i-1]$,预处理,用秦九韶算法看看$f(x)$是否为0(f运算时取模)。多枚举几个质数进行上述操作,对于$x\in [1,m]$,若对$\forall p_i, f(x\mathrm{mod}p_i)=0$,则$x$为一个解。
注意。如果枚举的$p_i$是个大质数,枚举$x\in[1,m]$在线判断$f(x\mathrm{mod}p_i)=0$,只能得70分。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define ll long long const int P[4] = {23333, 10007, 10003, 27777}; const int TotP = 4; const int MAX_STR_LEN = 10010; const int MAX_N = 110; const int MAX_M = 1000010; const int MAX_P = 30000; char S[MAX_N][MAX_STR_LEN]; ll A[MAX_N]; bool Mod_IsSol[MAX_P]; bool IsSol[MAX_M]; int M, N; ll ReadMod(const char *s, const ll p) { int len = strlen(s); int ans = 0, f = 1; for (int i = 0; i < len; i++) { if (s[i] == '-') { f = -1; continue; } ans = (ans * 10 + s[i] - '0') % p; } return ans * f; } bool Feq0(const ll x, const ll p, const ll *a, const int n) { ll cur = 0; for (int i = n; i >= 0; i--) cur = (cur * x + a[i]) % p; return cur == 0; } void Select(const ll p) { memset(Mod_IsSol, false, sizeof(Mod_IsSol)); for (int i = 0; i <= N; i++) A[i] = ReadMod(S[i], p); for (int i = 0; i < p; i++) if (Feq0(i, p, A, N)) Mod_IsSol[i] = true; for (int i = 1; i <= M; i++) if (!Mod_IsSol[i % p]) IsSol[i] = false; } int main() { scanf("%d%d\n", &N, &M); for (int i = 0; i <= N; i++) scanf("%s", S[i]); for (int i = 1; i <= M; i++) IsSol[i] = true; for (int i = 0; i < TotP; i++) Select(P[i]); int cnt = 0; for (int i = 1; i <= M; i++) cnt += IsSol[i]; printf("%d\n", cnt); for (int i = 1; i <= M; i++) if (IsSol[i]) printf("%d\n", i); return 0; }