• 【NOIP2014】解方程


    题目描述

    已知多项式方程

    \[a_0 + a_1x + a_2x^2 + \dots +a_nx^n=0 \]

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

    输入输出格式

    输入格式

    共 n + 2n+2 行。

    第一行包含 22 个整数 \(n\), \(m\) ,每两个整数之间用一个空格隔开。

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

    输出格式

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

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

    说明

    对于 \(30\%\) 的数据:\(0<n\le 2\),\(|a_i|\le 100\),\(a_n≠0\),\(m<100\)

    对于 \(50\%\) 的数据:\(0<n\le 100\),\(|a_i|\le 10^{100}\),\(a_n≠0\),\(m<100\)

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

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

    题解

    对于解方程,除了靠我机智的人脑我想不出除了暴力枚举解之外更好的方法了,但是,如果我们每次都进行枚举解,如何check呢?带回去算,哇,这个计算量我也是很震惊的,我们当然不能按着他的顺序来算啦,我们可以用秦九韶算法。


    秦九韶算法

    我们知道并没有直接求解高阶方程的公式,所以我们就没有办法直接求出我们所需要的答案,那么面对这个高阶多项式我们应该真么办呢?根据我们的观察,我们发现有下述的等价变形:

    \[a_0+a_1x+a_2x^2+\dots+a_nx^n\\ \ \ \ \ \ \ \ =a_0+x(a_1+x(a_2+\dots+x(a_n)\dots))) \]

    我们从最里面的括号算起,我们会发现假设我们已经算出了第\(i\)个括号中的答案是\(ans_i\),我们再算第\(i + 1\)个括号时是这样算的:\(a_{i-1}+ans_ix\)其实我们数算出的\(ans_i\)就成了下一个括号中\(x\)的系数了。这样的话我们就可以利用一个\([1,n]\)的for循环搞定了,模板长成这个样子:

    xs  = 0;
    for(int i = n; i >= 1; -- i)	
        xs = ((xs + a[i]) % mod * x)% mod;
    

    仅仅知道这个离AC这道题还有一段距离,我们来看一下数据,哇这个范围是要写高精的吗???,显然,高精这种麻烦的东西我们要放在最后来考虑。我们观察到,如果有\(f(x)mod \ \ p=0\)那么\(f(xmod\ \ p) mod\ \ p= 0\)
    那么我们只用在每次计算之后进行一个取模操作就行了,为了避免冲突,我们选取一个较大的质数作为我们的模数(我选的是\(10^9+7\)),在输入的过程中我们也可以一边输入一边对输入的数进行取模,这个改一下读入优化就可以实现了。

    long long read()
        {
            long long x = 0; int w = 0; char ch= getchar();
            for(;!isdigit(ch); w |= (ch == '-'),ch = getchar());
            for(;isdigit(ch);x = ((x << 1) + (x<< 3)) % mod + (ch ^48), ch = getchar());
            return w ? -x : x;
        }
    

    代码

    #include<bits/stdc++.h>
    using namespace std;
    long long a[105], ans[1000005], xs;
    const long long mod = 1e9 + 7;
    long long read()
        {
            long long x = 0; int w = 0; char ch = getchar();
            for(;!isdigit(ch); w |= (ch == '-'), ch = getchar());
            for(;isdigit(ch);x = ((x << 1) + (x << 3)) % mod + (ch ^ 48), ch = getchar());
            return w ? -x : x;
        }
    int main()
    {
        int n, cnt = 0;
        long long m;
        scanf("%d%lld", &n, &m);
        for(int i = 0; i <= n; ++ i)	a[i] = read(), a[i] = a[i] % mod;
        for(long long x = 1; x <= m; ++ x)
            {
                xs  = 0;
                for(int i = n; i >= 1; -- i)	
                    xs = ((xs + a[i]) % mod * x) % mod;
                if((xs + a[0]) % mod == 0)	ans[++ cnt] = x;
            }
        printf("%d\n", cnt);
        for(int i = 1; i <= cnt; ++ i)	printf("%d\n", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    NOI 2019 网络同步赛 游记
    洛谷 P3695 CYaRon!语 题解 【模拟】【字符串】
    洛谷 P2482 loj #2885 [SDOI2010]猪国杀 题解【模拟】【贪心】【搜索】
    Spring MVC @ResponseBody返回中文字符串乱码问题
    Hibernate4中使用getCurrentSession报Could not obtain transaction-synchronized Session for current thread
    @Value取不到值引出的spring的2种配置文件applicationContext.xml和xxx-servlet.xml
    @RestController注解下返回到jsp视图页面
    Mysql引起的spring事务失效
    Eclipse中启动tomcat报错:A child container failed during start
    xshell不能输入中文,显示为??
  • 原文地址:https://www.cnblogs.com/pxyWaterMoon/p/9549284.html
Copyright © 2020-2023  润新知