noip2014解方程题解

时间:2022-12-16 15:45:32

其实这道题看上去像一道高大上的数论题,但是实际上一般般,看完题解整个人都蒙蔽了

这道题考察的在模域内解决问题的能力。我们注意到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

*/