• [Noip2014] 解方程


    题目描述

    已知多项式方程: $$a_0+a_1x+a_2x^2+cdots+a_nx^n=0$$

    求这个方程在 $[1,m]$ 内的整数解( $n$ 和 $m$ 均为正整数)。


    输入输出格式

    输入格式:

    输入共 $n + 2$ 行。

    第一行包含 $2$ 个整数 $n, m$ ,每两个整数之间用一个空格隔开。

    接下来的 $n+1$ 行每行包含一个整数,依次为 $a_0,a_1,a_2ldots a_n$ 。

    输出格式:

    第一行输出方程在 $[1,m]$ 内的整数解的个数。

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


    输入输出样例

    输入样例#1: 
    2 10 
    1
    -2
    1
    输出样例#1: 
    1
    1
    输入样例#2: 
    2 10
    2
    -3
    1
    输出样例#2: 
    2
    1
    2
    输入样例#3: 
    2 10 
    1  
    3  
    2  
     
    输出样例#3: 
    0

    说明

    对于 $30\%$ 的数据: $0<nle 2,|a_i|le 100,a_n≠0,m<100$ 。

    对于 $50\%$ 的数据: $0<nle 100,|a_i|le 10^{100},a_n≠0,m<100$ 。

    对于 $70\%$ 的数据: $0<nle 100,|a_i|le 10^{10000},a_n≠0,m<10^4$ 。

    对于 $100\%$ 的数据: $0<nle 100,|a_i|le 10^{10000},a_n≠0,m<10^6$ 。


    疯狂加美元符结果都没有用好伤心啊。

    一看数据范围就知道这题一般的算法做不出来,这数据范围高精度过不去...

    挣扎了一下午无望然后膜拜题解。

    wow!这太神了。

    这题要我在考场上绝对想不出来。

    谁脑洞这么大想出取模的方法啊233了。

    先把输入的$ large ai $对一个素数取模然后用秦九韶算。

    我们设原函数为$ large f[] $。

    那么$ large f[x]%p=0%p=0 $。

     所以取一个素数当模数就行了。

    然而50分。

    因为以上的算法冲突的概率是很大的, 解决方法就是多取几个模数。

    然后70,剩下的TLE。

    如何解决?

    我们考虑,$ large f[x]%p!=0, f[x*k+b]%k!=0 $.

    所以我们只需要求出1~mod-1的答案就行了。


    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    using namespace std;
    #define reg register
    #define ll long long
    #define int long long
    
    int n, m;
    int a[105][3];
    bool can[1000004][3];
    int p[3] = {23333, 23537, 15733};
    char ch[10005];
    int ans[1000005], cnt;
    
    signed main()
    {
        scanf("%lld%lld", &n, &m);
        for (reg int i = 0 ; i <= n ; i ++)
        {
            memset(ch, 0, sizeof ch);
            scanf("%s", ch + 1);
            int len = strlen(ch + 1);
            int tmp[3] = {0}, fu = 1;
            int j = 1;
            if (ch[1] == '-') fu = -1, j = 2;
            for (j ; j <= len ; j ++)
                for (reg int k = 0 ; k <= 2 ; k ++)
                    tmp[k] = (tmp[k] * 10 + ch[j] - '0') % p[k];
            for (reg int k = 0 ; k <= 2 ; k ++)
            {
                a[i][k] = tmp[k];
                if (fu == -1) a[i][k] = p[k] - a[i][k];
            }
        }
        for (reg int i = 0 ; i <= mod ; i ++)
        {
            for (reg int k = 0 ; k <= 2 ; k ++)
            {
                ll sum = a[n][k];
                for (reg int j = n - 1 ; j >= 0 ; j --)
                    sum = ((a[j][k] + sum * i) % p[k] + p[k]) % p[k];    
                if (!sum) can[i][k] = 1;
            }
        }
        for (reg int i = 1 ; i <= m ; i ++)
        {
            for (reg int k = 0 ; k <= 2 ; k ++)
                if (!can[i%p[k]][k])  goto End;
            ans[++cnt] = i;
            End:;
        }
        printf("%lld
    ", cnt);
        for (reg int i = 1 ; i <= cnt ; i ++)
            printf("%lld
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    codna的安装与使用
    ubuntu 下修改MySQL 的root用户密码
    python中的排序
    CF 543C Remembering Strings
    CF 1119C Ramesses and Corner Inversion
    HihoCoder 1384 Genius ACM
    BZOJ3032 七夕祭
    Vjudge Code
    CF51C Three Base Stations
    Sumdiv POJ 1845
  • 原文地址:https://www.cnblogs.com/BriMon/p/9525884.html
Copyright © 2020-2023  润新知