前几天看到这道题,感觉蛮有意思,就来写篇题解吧。
题面很清楚,应该没什么理解上的问题吧
首先看到这题想到什么,最暴力的写法就是从1到 m m m枚举啊,把每个 x x x的值代入,看能否成立,但是这显然不行(不要问我怎么知道的,难道提高组的题这么水???)
首先,这题的确是得要枚举,但是不是暴力枚举,不是每次都把 x 0 , x 1 , . . . , x n x^0,x^1,...,x^n x0,x1,...,xn算出来的不然那样效率太低了。。。。。
这是就有了一个玄学的秦九韶算法:
具体的过程就是:
f
(
x
)
f(x)
f(x)
= a 0 + a 1 x + a 2 x 2 + ⋯ + a n x n =a_0+a_1x+a_2x^2+\cdots+a_nx^n =a0+a1x+a2x2+⋯+anxn
= a n x n + a i − 1 x n − 1 + ⋯ + a 1 x + a 0 =a_nx^n+a_{i-1}x^{n-1}+\cdots+a_1x+a_0 =anxn+ai−1xn−1+⋯+a1x+a0
= ( a n x n − 1 + a i − 1 x n − 2 + ⋯ + a 2 x + a 1 ) x + a 0 =(a_nx^{n-1}+a_{i-1}x^{n-2}+\cdots+a_2x+a_1)x+a_0 =(anxn−1+ai−1xn−2+⋯+a2x+a1)x+a0
=
(
(
a
n
x
n
−
2
+
a
i
−
1
x
n
−
3
+
⋯
+
a
3
x
+
a
2
)
x
+
a
1
)
x
+
a
0
=((a_nx^{n-2}+a_{i-1}x^{n-3}+\cdots+a_3x+a_2)x+a_1)x+a_0
=((anxn−2+ai−1xn−3+⋯+a3x+a2)x+a1)x+a0
.
\LARGE.
.
.
\LARGE.
.
.
\LARGE.
.
=
(
⋯
(
(
a
n
x
+
a
n
−
1
)
x
+
a
n
−
2
x
+
⋯
+
a
1
)
x
+
a
0
=(\cdots((a_nx+a_{n-1})x+a_{n-2}x+\cdots+a_1)x+a_0
=(⋯((anx+an−1)x+an−2x+⋯+a1)x+a0
通过这个式子我们可以知道:
对于一个n次多项式,至多做n次乘法和n次加法
就是这样喽
吐槽个东西:那天在寝室里讲到秦九韶算法,同寝一位数学班巨佬说:“这秦九韶算法这么丑,不好用。”
我:“emmmmm,反正这东西手算是真的麻烦,不如一个一个算,但是到了信息上就不一样了,一次循环就搞定了,贼方便。”
还有一个就是这题读入的问题,就是得用快读再加点奇怪的东西
const int q=1000000007;
ll read()
{
ll sum=0;
ll flag=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
{
flag=-1;//负数
}
c=getchar();
}
while(c>='0'&&c<='9')
{
sum=((sum*10)+c-'0')%q;//由于a很大得取模
c=getchar();
}
return sum*flag;
}
q
q
q最好是大质数
接下来就是完整code了!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int twx=1000000+100;
const int q=1000000007;//取模用的大质数
int n,m;
int a[twx]={};
int sum=0;
int cnt=0;
int ans[twx];
bool t=true;//判断是否有答案
ll read()
{
ll sum=0;
ll flag=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
{
flag=-1;//负数
}
c=getchar();
}
while(c>='0'&&c<='9')
{
sum=((sum*10)+c-'0')%q;//由于a很大得取模
c=getchar();
}
return sum*flag;
}
bool jian(ll x)
{
sum=0;
for(int i=n;i>=1;i--)
{
sum=((a[i]+sum)*x)%q;//秦九昭算法求多项式的值
}
sum=(sum+a[0])%q;//再加上a[0]
if(sum)//如果sum为0的话说明x为多项式的值,返回true
{
return false;
}
else
{
return true;
}
}
void init()
{
cin>>n>>m;
for(int i=0;i<=n;i++)
{
a[i]=read();//由于数太大了,得在读入时进行一些操作
}
}
void work()
{
for(int i=1;i<=m;i++)
{
if(jian(i))//有解
{
t=false;//cnt为答案个数
ans[++cnt]=i;//记录答案
}
}
}
void print()
{
if(t)
{
cout<<0;
exit(0);
}
else
{
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
{
cout<<ans[i]<<endl;
}
}
}
int main()
{
init();
work();
print();
return 0;
}