• 【数学】【NOIP2013】解方程


    Description

    已知多项式方程: a0+a1x+a2x^2+...+anx^n=0 求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。

    Input Format

    输入共 n+2 行。 第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。 接下来的 n+1 行每行包含一个整数,依次为a0, a1, a2, ..., an。

    Output Format

    第一行输出方程在[1, m]内的整数解的个数。 接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

    Sample Input

    样例输入1
    2 10
    1
    -2
    1
    
    样例输入2
    2 10
    2
    -3
    1
    
    样例输入3
    2 10
    1
    3
    2
    

    Sample Output

    样例输出1
    1
    1
    
    样例输出2
    2
    1
    2
    
    样例输出3
    0

    Solution

    (毒瘤王f-void用70%的做法+O3优化过了 导致一堆大佬紧跟其后 不打正解 所以……)
    正解要用到一个性质 因为方程左边等于0 0 mod 任何数都为0
    若 x % k=0 那么 (x+nk) %k =0
    枚举1-k的数 作为x判断方程左边是否为0
    为0则为解
    而 k+1 - n的数 只要通过 前面的数+nk就可以得到
    比如0+k=k 1+k=k+1; 所以我们只要枚举1 - k-1就行了
    k应该选择素数 并且多组
    因为可能存在x 使方程左边为k的倍数
    这样mod也是0 但并不是方程的解
    选择多组保证数据准确
    因为a很大 读入应该用字符读 边读边%
    计算方程左边的值时,可以用(秦九韶?),
    我的写法是((an*x+an-1)*x+an-2)*x……)*x;
    #include<cstdio>
    #include<cstring>
    
    int n,m;
    int a[5][105];
    int f[5][10005];
    int pri[5]= {9931,9941,9949,9967,9973};
    int ans[1000005],ansl;
    
    int read()
    {
        char c=getchar();
        int temp=0,f=1;
        while (c<'0'||'9'<c)
        {
            if (c=='-') f=-1;
            c=getchar();
        }
        while ('0'<=c&&c<='9')
        {
            temp=temp*10+c-'0';
            c=getchar();
        }
        return temp*f;
    }
    
    bool judge(int i)
    {
        for (int t=0; t<5; t++)
        {
            if (f[t][i%pri[t]]) return false;
        }
        return true;
    }
    
    int main()
    {
        n=read();
        m=read();
        for (int i=0; i<=n; i++)
        {
            char ch[10005];
            scanf("%s",ch);
            int len=strlen(ch),z=0;
            for (int t=0; t<5; t++)
            {
                if (ch[0]=='-') a[t][i]=0,z=1;
                else a[t][i]=ch[0]-'0';
            }
            for (int t=0; t<5; t++)
            {
                for (int j=1; j<=len-1; j++)
                {
                    a[t][i]=(a[t][i]*10+ch[j]-'0')%pri[t];
                }
                if (z==1) a[t][i]=-a[t][i];
            }
        }
        for (int t=0; t<5; t++)
        {
            for (int x=1; x<=pri[t]; x++) //((an*x+an-1)*x+an-2)*x;
            {
                int temp=0;
                for (int i=n; i>=0; i--)
                {
                    temp=(temp*x+a[t][i])%pri[t];
                }
                f[t][x%pri[t]]=temp;
            }
        }
        for (int i=1; i<=m; i++)
        {
            if (judge(i))
            {
                ans[++ansl]=i;
            }
        }
        printf("%d\n",ansl);
        for (int i=1; i<=ansl; i++) printf("%d\n",ans[i]);
    }
  • 相关阅读:
    洛谷 P1313 计算系数
    洛谷 P1088 火星人
    洛谷 P1049 装箱问题
    P5016 龙虎斗
    洛谷P1208
    求lca
    没有上司的舞会
    最短路spfa
    懒羊羊找朋友
    简单的图论问题之单源最短路dijkstra算法
  • 原文地址:https://www.cnblogs.com/Shawn7xc/p/7689398.html
Copyright © 2020-2023  润新知