[NOIP2014]解方程

看起来一脸高精+不可做的样子。。。但实际上是非常可做的。
高中数学必修三上面有一个算法是秦九韶算法。用这个算法做就行了。
但是那个高精度让人看的崩溃。但是我们的需求只有求左边这个式子答案是不是0,所以可以多膜几个不太大的数,为保证正确性,%了5个。时间复杂度是2w多的一个数*n+m。可以过
但是bzoj太慢了,卡的我差点没过。
luogu数据太水了,机器跑的又比\(€€₣\)的不知道快到哪里去了,nm+大常数的也能过。。。

/**************************************************************
    Problem: 3751
    Language: C++
    Result: Accepted
    Time:9872 ms//bzoj太慢了!
    Memory:15460 kb
****************************************************************/
 
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
const int mod[]={11261,19997,22877,21893,14843};
int s[6][102];
char a[10005];
inline bool calc(int id,long long x) {
    int ans=s[id][n];
    for(int i=n-1;~i;i--) {
        ans=(ans*x+s[id][i])%mod[id];
    }if(ans) return 1;return 0;
}
int ans[105][25000];
inline bool cal(int x) {
    for(int i=0;i<5;i++) if(ans[i][x%mod[i]])return 0;
    return 1;
}
int stk[1000005],top;
int main() {
    scanf("%d%d",&n,&m);
    for(int i=0,len;i<=n;i++) {
        scanf("%s",a);
        len=strlen(a);
        int j=0,f=1;
        if(a[0]=='-') f=-1,j=1;
        else j=0,f=1;
        for(j;j<len;j++) for(int k=0;k<5;k++) s[k][i]=(s[k][i]*10+a[j]-'0')%mod[k];
        for(int k=0;k<5;k++) s[k][i]*=f;
    }
    for(int i=0;i<5;i++) 
        for(int j=0;j<=22876;j++) 
            ans[i][j]=calc(i,j);
    for(int i=1;i<=m;i++) if(cal(i)) stk[++top]=i;
    printf("%d\n",top);
    for(int i=1;i<=top;i++) printf("%d\n",stk[i]);
}
posted @ 2018-09-07 20:12  SWHsz  阅读(160)  评论(0编辑  收藏  举报