luogu2312 解方程
阿新 • • 發佈:2018-10-01
algo tin ems brush highlight strlen include %d long
題目大意
已知多項式方程: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; }
luogu2312 解方程