其实这道题看上去像一道高大上的数论题,但是实际上一般般,看完题解整个人都蒙蔽了
这道题考察的在模域内解决问题的能力。我们注意到n是小于100的,也就是说a其实只有100个。数据那么大,根本无法解决。但是我们注意到,式子的形式是:a0+a1x+a2x^2+..+anx^n=0。那么如果说两边同时模上一个数,会怎样呢
(a0+a1x+a2x^2+..+anx^n)%k=0%k=0我们发现,如果在不起冲突的情况下,模一个数其实并不影响到这个方程的答案。为了避免冲突,就多模几个数,然后分别验证就可以了。。。就是这样子的。。。。
额,还有一个优化,你千万不要傻傻的去吧x的一百次方乘上去,那会死人的,正解是这里:
(((an+x)*an-1+x)*an-2+x……)*x+a0=0;
这题就这样咯!
贴代码:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const intmod[5]={22861,22871,22877,22901,22907};
int top=0;
int a[5][1000001];
char sa[1000001];
bool b[5][30001];
void pd(int i,int k)
{
intans=0;
for(intj=top;j>=1;j--) ans=(ans*i+a[k][j])%mod[k];
if(!ans)b[k][i]=1;
}
int main()
{
intn,m;
boolp=0;
scanf("%d%d",&n,&m);
for(inti=1;i<=n+1;i++)
{
scanf("%s",sa);
intnn=strlen(sa),x=1,jj=0;
if(sa[0]=='-')x=-1,jj++;
if(sa[0]=='+')jj++;
top++;
for(intk=0;k<=4;k++)
{
intans=0;
for(intj=jj;j<nn;j++) ans=(ans*10+sa[j]-'0')%mod[k];
a[k][top]=ans*x%mod[k];
if(a[k][top]<0)a[k][top]+=mod[k];
}
}
for(intk=0;k<=4;k++)
for(inti=1;i<=mod[k];i++)
{
pd(i,k);
}
intans=0;
queue<int>q;
for(inti=1;i<=m && ans<=n;i++)
{
boolp=1;
for(intk=0;k<=4;k++)
{
p=p&b[k][i%mod[k]];
}
if(p)ans++,q.push(i);
}
printf("%d\n",ans);
for(inti=1;i<=ans;i++)
{
printf("%d\n",q.front());
q.pop();
}
return0;
}
/*
2 10
1
-2
1
2 10
2
-3
1
*/