题目描述
已知多项式方程:
a0+a1x+a2x2+..+anxn=0 a 0 + a 1 x + a 2 x 2 + . . + a n x n = 0
求这个方程在[1, m ] 内的整数解(n 和m 均为正整数)
输入输出格式
输入格式:
输入文件名为equation .in。
输入共n + 2 行。
第一行包含2 个整数n 、m ,每两个整数之间用一个空格隔开。
接下来的n+1 行每行包含一个整数,依次为 a0 a 0 , a1 a 1 , a2 a 2 … an a n
输出格式:
输出文件名为equation .out 。
第一行输出方程在[1, m ] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m ] 内的一个整数解。
输入输出样例
输入样例#1:
2 10
1
-2
1
输出样例#1:
1
1
输入样例#2:
2 10
2
-3
1
输出样例#2:
2
1
2
输入样例#3:
2 10
1
3
2
输出样例#3:
0
说明
对于30%的数据: 0<n<=2,|ai|<=1e2,an!=0,m<1e2 0 < n <= 2 , | a i | <= 1 e 2 , a n ! = 0 , m < 1 e 2
对于50%的数据: 0<n<=1e2,|ai|<=1e100,an!=0,m<1e2 0 < n <= 1 e 2 , | a i | <= 1 e 100 , a n ! = 0 , m < 1 e 2
对于70%的数据: 0<n<=1e2,|ai|<=1e10000,an!=0,m<1e4 0 < n <= 1 e 2 , | a i | <= 1 e 10000 , a n ! = 0 , m < 1 e 4
对于100%的数据: 0<n<=1e2,|ai|<=1e10000,an!=0,m<1e6 0 < n <= 1 e 2 , | a i | <= 1 e 10000 , a n ! = 0 , m < 1 e 6
题目概要
说实话只要语文比我好的应该都看得懂题 ,我都看得懂题,还有谁看不懂
毫不谦虚地挂上自己的中考模考成绩单:
生地体:A 理综:A 文综:A 数学:A 英语:A 语文:D 总成绩:5A1D buff:全校唯一一个5A1D的学生
我想应该没有语文比我弱的了吧
思路
乍一看数据
就觉得正解应该是 O(nlogm) O ( n l o g m ) 或 O(mlogn) O ( m l o g n ) 的复杂度
美好愿景
要是这题不要求求出所有的解,可以二分m求解,复杂度 O(n2log2m) O ( n 2 l o g 2 m ) ,其中 O(n2) O ( n 2 ) 求解一个式子, O(log2m) O ( l o g 2 m ) 是二分复杂度
但是
这题要求求出所有解,必须枚举每一个解 反正我是想不出什么好方法
既然
现在m的复杂度已经确定了,再看看m=1e6,n岂不是只剩下10的生存空间了,再看看n
看看我们的复杂度 O(n2m) O ( n 2 m ) ,其中m为1e6,这表示着关于 n n 的复杂度必须变为或 O(n) O ( n )
继续
但是我们看到,长度为n的a数组是要求我们输入的啊,所以好像没有什么方法可以把它压到线性复杂度一下吧
接着
我们发现我们只能把时间压成 O(nm) O ( n m ) ,那么只能在求多项式值中入手,暴力求解固然 O(n2) O ( n 2 ) ,但突然发现,有一个神奇的方法叫做秦九韶算法(与其叫算法不如叫公式)
下面给出概要:
对于一个函数
的复杂度从 O(n2) O ( n 2 ) 降到O(n)了,于是复杂度问题就解决了
但是应该可以看到a数组是一个高精度数字
那该咋办?
于是神奇海螺告诉我们:
这时我们就选择玄学的力量,对于高精度数,我们果断使用读入优化读入高精度,在读入优化时每独一位膜一个大质数,计算ans值时也要不停地膜大质数
至于为什么?
另外,由于我们最终复杂度为 O(nm) O ( n m ) n=1e2,m=1e6,所以最终要用到卡常技巧
看程序吧
我们惊奇地发现这个程序是可以AC的,所以
#include<bits/stdc++.h>
using namespace std;
#define rg register
typedef long long ll; //最后千万别忘了开long long,因为这个调了一上午
const int mod=1e9+7;
template <typename _Tp> inline void read(_Tp &x){
char c11=getchar();x=0;bool booo=0;
while(c11<'0'||c11>'9'){if(c11=='-')booo=1;c11=getchar();}
while(c11>='0'&&c11<='9'){x=(x*10+c11-'0')%mod;c11=getchar();} //可以试试不膜大质数的结果
if(booo)x=-x;
return ;
}
const int maxn=101;
ll a[maxn];int st[1000005],p=0;
int n,m;
void init();
inline bool check(int x){
rg ll sum=0;
for(rg int i=n;i>-1;--i)
sum=((a[i]+sum)*x)%mod; //这里也要膜大质数
return sum==0;
}
void work(){
for(rg int i=1;i<=m;++i)if(check(i))st[++p]=i;
check(65536);
printf("%d\n",p);for(rg int i=1;i<=p;i++)printf("%d\n",st[i]);//压行你咬我啊
return ;
}
int main(){ // freopen("in","r",stdin); freopen("1.out","w",stdout);
init();
work();
return 0;
}
void init(){
read(n);read(m);
for(rg int i=0;i<=n;++i)read(a[i]);
}