[NOIP2014]解方程 (暑假ACM1 H)

题意

求方程a0+a1x+a2x2+⋯anxn=0在[1,m]内的解。

对于100% 的数据:0<n<=100,|ai|<=1010000,an≠0,m<1060

题解

当时是sxk大佬给我说的他的思路,因为题目有暗示  Hint:如果那是个模方程,求 (mod 10007)时 x%10007的各种解,那么我就会做了。

所以他就说先对系数取模,然后求出[0,10006]的解,然后如果一个解是x0,那么(x0+10007)也是一个解,因为在将各种次方展开时,有10007系数的都模掉了,就变成了原方程。

所以我看了看数据,ai怎么模?高精度???我问出了这个愚蠢的问题,可以利用快读边读入边取模,而且这个问题原来遇到过,我都忘了[菜鸡]

不过我从一开始就产生了一种顾虑,就是就算是模方程,那左边计算不取模就可能爆掉,取模万一是10007的倍数最后得到0,不过这并不是一个正确解。

还好这个是正确的,不然又打脸。

后来又想到了取多个模数,并且想到了要用秦九韶算法,可是却跑偏了,因为要枚举[1,m]的数,就因为过不去,最后没敲。

现在想想,其实挺简单的。

#include<bits/stdc++.h>
using namespace std;

#define ll long long
const int mod1=10007;
const int mod2=1000000007;
const int maxm=1000005;
int n,m;
ll a[105],b[105];
int ans[maxm];
bool cx[10010];

inline void read(int i){
    ll x=0,y=0;int f=0;char ch=getchar();
    while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
    while(isdigit(ch)){x=x*10%mod1+ch-'0';y=y*10%mod2+ch-'0';ch=getchar();}
    if(f) x=-x,y=-y;
    a[i]=x;b[i]=y;
}

bool nice(ll x){
    ll ret=0;
    for(int i=n;~i;i--)
     ret=(ret*x+a[i])%mod1;
    return !ret;
}

bool sto324(ll x){
    ll ret=0;
    for(int i=n;~i;i--)
     ret=(ret*x+b[i])%mod2;
    return !ret;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++) read(i);
    //for(int i=0;i<=n;i++) printf("%d %d\n",a[i],b[i]);
    for(int i=0;i<mod1;i++)
     if(nice(i)) 
      cx[i]=true;
    for(int i=1;i<=m;i++)
     if(cx[i%mod1]&&sto324(i))
      ans[++ans[0]]=i;
    for(int i=0;i<=ans[0];i++)
     printf("%d\n",ans[i]);
}
View Code

 

posted @ 2019-07-21 21:13  _JSQ  阅读(318)  评论(0编辑  收藏  举报