NOIP2014 lgP2312 解方程(秦九韶演算法+hash)
阿新 • • 發佈:2019-02-17
題面
題解
這題十分玄學,貌似想破頭都只有50分的暴力。
什麼牛頓迭代法、FFT各種牛B演算法好像都不行,高精度只有暴力分。
正解基於以下
逆命題明顯不對,但是多搞幾個質數做
然後多項式
於是我們就弄五個質數,每個質數要很適合AC,是什麼樣請參考程式碼。然後預處理出個表,
時間就是
神奇的程式碼
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n, m, a[5][105], f[5][20050], ans[105];
const int prime[] = {20011, 20021, 20023, 20029, 20047};
const int cnt = 5;
void Read(int x){
bool f = true;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = false; ch = getchar();}
int ret[5];
for(int i = 0; i < cnt; i++) ret[i] = 0 ;
while(ch >= '0' && ch <= '9'){
for(int i = 0; i < cnt; i++)
ret[i] = ((ret[i] << 3) + (ret[i] << 1) + ch - '0') % prime[i];
ch = getchar();
}
for(int i = 0; i < cnt; i++)
a[i][x] = f ? ret[i] : prime[i] - ret[i];
}
int calc(int t, int x){
int ret = 0;
for(int i = n; i >= 0; i--)
ret = (ret * x + a[t][i]) % prime[t];
return ret;
}
int main(){
freopen("lgP2312.in", "r", stdin);
freopen("lgP2312.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++) Read(i);
for(int i = 0; i < cnt; i++)
for(int j = 0; j < prime[i]; j++)
f[i][j] = calc(i, j);
for(int i = 1; i <= m; i++){
bool ok = true;
for(int j = 0; j < cnt; j++)
if(f[j][i % prime[j]]) ok = false;
if(ok)
ans[++ans[0]] = i;
}
printf("%d\n", ans[0]);
for(int i = 1; i <= ans[0]; i++)
printf("%d\n", ans[i]);
return 0;
}
答案是偶然?必然?
你曾經選擇的道路,才是真正的命運。
緊握在手心的希望也好、不安也罷,
必定會化作驅使我們前進的光。