【數論】[漲姿勢:同餘]P2312解方程

題目描述

已知多項式方程:\(a_0 + a_1x + a_2x^2+...+a_nx^n = 0\)

求這個方程在[1,m]內的整數解

\(1\leq n\leq100,|a_i|\leq 10^{10000},a_n≠0,m\leq 10^6\)

Solution

首先由於數據過大,只能字符串讀入了hhh。然後:對於每個x,算出f(x)%pi,如果f(x)=0則f(x)%pi必然=0,多選幾個素數,就可以在一定範圍大小內判斷成功。好像不夠快?

\(f(x+p)≡f(x)(mod p)\)

對於一個x,\(f(x)≠0(mod p)\),則x+p,x+2p……均不爲方程的解

有了這個性質就可以瞎搞了。取幾個較大的質數搞一搞……

Code

#include <iostream>
#include <cstdio>
using namespace std;
inline long long read() {
  long long x = 0; int f = 0; char c = getchar();
  while (c < '0' || c > '9') f |= c == '-', c = getchar();
  while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  return f? -x:x;
}

long long a[110][4], mod[4] = {10007, 11003, 12007, 13001};
int b[1000010], n, m;
string qwq;
bool check(long long x) {
  for (int k = 0; k < 4; k++) {
    long long tmp = a[n][k];
    for (int i = n - 1; i >= 0; i--)
      tmp = (tmp * x + a[i][k]) % mod[k];
    if (tmp) {
      for (int i = x; i <= m; i += mod[k]) b[i] = 1;
      return 0;
    }
  }
  return 1;
}
int main() {
  n = read(); m = read();
  for (int i = 0; i <= n; ++i) {
    cin >> qwq;
    for (int k = 0; k < 4; ++k) {
      long long flg = 1, tmp = 0;
      for (int j = 0; j < qwq.length(); ++j)
        if (qwq[j] == '-') flg = -1;
        else tmp = ((tmp << 1) + (tmp << 3) + (qwq[j] ^ 48)) % mod[k];
        a[i][k] = tmp * flg;
      }
  }
  int ans = 0;
  for (int x = 1; x <= m; x++)
    if (!b[x] && check(x)) ans++;
  printf("%d\n", ans);
  for (int i = 1; i <= m; i++)
    if (!b[i]) printf("%d\n", i);
  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章