题目描述
已知多项式方程:
a_0+a_1x+a_2x^2+\cdots+a_nx^n=0a0+a1x+a2x2+⋯+anxn=0
求这个方程在 [1,m][1,m] 内的整数解(nn 和 mm 均为正整数)。
输入输出格式
输入格式:
共 n + 2n+2 行。
第一行包含 22 个整数 n, mn,m ,每两个整数之间用一个空格隔开。
接下来的 n+1n+1 行每行包含一个整数,依次为 a_0,a_1,a_2\ldots a_na0,a1,a2…an 。
输出格式:
第一行输出方程在 [1,m][1,m] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在 [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\%30% 的数据:0<n\le 2,|a_i|\le 100,a_n≠0,m<1000<n≤2,∣ai∣≤100,an≠0,m<100 。
对于 50\%50% 的数据:0<n\le 100,|a_i|\le 10^{100},a_n≠0,m<1000<n≤100,∣ai∣≤10100,an≠0,m<100 。
对于 70\%70% 的数据:0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^40<n≤100,∣ai∣≤1010000,an≠0,m<104 。
对于 100\%100% 的数据:0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^60<n≤100,∣ai∣≤1010000,an≠0,m<106 。
这么这么这么这么这么这么这么这么这么这么这么这么这么这么这么这么这么这么大的数
除了高精度只有hash了,但高精度显然超时
所以·只能hash,
又因为单hash被卡,不信可以去刷一下BZOJ上的
但是双hash是安全的,bzoj上只有ZERO个人通过了
如果你担心,也可以写多hash
不过看起来只有70分(不过noip够了不对吗?)
读入优化输出优化开起来,能用位运算尽量使用,
判断是否为0的时候可以使用秦九韵算法(不就是分治吗?)
a0+x*a1+x^2*a2+……+x^n*an
=a0+x*(a1+x*a2+……+x^n-1*an)
=……
这不就是分治吗
公式不用写了自己去推吧(不是博主懒,而是博主想给你们思考一下:))
#include<cstdio>
#define ll long long
const int p1=1e9+7,p2=6662333;
using namespace std;
const int N=105,M=1e6+5;;
int n,m,num,ans[M];
ll a1[N],a2[N];
void write(int x)
{
if(!(x/10))
{
putchar(x+48); return;
}
write(x/10),putchar(x%10+48);
}
void read(int i)
{
bool f=0;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
a1[i]=((a1[i]<<1)+(a1[i]<<3)+ch-'0')%p1,
a2[i]=((a2[i]<<1)+(a2[i]<<3)+ch-'0')%p2,
ch=getchar();
if(f) a1[i]=-a1[i],a2[i]=-a2[i];
}
inline bool pd(int x)
{
ll ret=a1[n];
for(int i=n-1;i>=0;i--)
ret=(ret*x+a1[i])%p1;
if(ret!=0) return 0;
ret=a2[n];
for(int i=n-1;i>=0;i--)
ret=(ret*x+a2[i])%p2;
return ret==0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) read(i);
num=0;
for(int i=1;i<=m;i++)
if(pd(i)) ans[++num]=i;
write(num),puts("");
for(int i=1;i<=num;i++)
write(ans[i]),puts("");
return 0;
}