NOIP2014解方程解题报告

本文介绍了一种高效的多项式计算方法——秦九韶算法,并通过一道具体题目详细展示了如何利用此算法来减少计算复杂度,实现快速求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题见洛谷(https://www.luogu.org/problem/show?pid=2312
QWQ
好像有一个东西叫秦九韶算法~这个东西就是用来计算多项式值的一种方法能减少运算次数发一下百度百科的秦九韶算法的解释吧~不过这是高中数学的内容基本上上过高中的应该都知道吧TAT链接:(https://baike.baidu.com/item/秦九韶算法/449196?fr=aladdin)
这道题呢我们可以吧左边的当成多项式来算用秦九韶算法就行了啊~

inline bool qjs(long long x){
    sum=0;
    for(register int i=n;i>=0;i--){
        sum=((a[i]+sum)*x)%p;
    }
    return !sum;
}

下面的思路就是逐个从1~m枚举算式的值,只要这个算式的值是0就计数好了
先贴一下代码在讲解吧~嗷呜~

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int p=1000000007;
long long a[110],key[1000000];
bool t=true;
int ans=0,cnt,sum=0;
int n,m;

inline long long read(){
    long long sum=0,fg=1;
    char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-'){
            fg=-1;
        }
        c=getchar();
    }
    while(c>='0' && c<='9'){
        sum=((sum*10)+c-'0')%p;
        c=getchar();
    }
    return sum*fg;
}
inline void out(int x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9){
        out(x/10);
    }
    putchar(x%10+'0');
}
inline bool qjs(long long x){
    sum=0;//一定要清零
    for(register int i=n;i>=0;i--){
        sum=((a[i]+sum)*x)%p;
    }
    return !sum;
}

int main(){
    n=read();
    m=read();
    for(register int i=0;i<=n;i++){
        a[i]=read();
    }
    for(register int i=1;i<=m;i++){
        if(qjs(i)){
            t=false;
            ans++;
            cnt++;
            key[cnt]=i;
        }
    }
    if(t){
        out(ans);
        printf("\n");
        return 0;   
    }
    out(ans);
    printf("\n");
    for(register int i=1;i<=cnt;i++){
        out(key[i]);
        printf("\n");
    }
    return 0;
}

p是一个大的质数,防止爆int,可以记得读入优化的时候也膜一下,
然后呢read和out函数就是快速读入和快速输出啦~
bool t就是用t来判断是否有解。cnt来记录解的个数。sum来记录多项式的结果,记得在qjs函数里一定要把sum清零,否则就是10分,a数组就是来记录多项式系数的值的,key数组是用来记录每个解的值的
发一份有注释的题解:

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int p=1000000007;//取模比较方便为
bool t=true;//用来判断是否有解 
int n,m,ans,cnt,sum=0;//cnt记录解的个数;sum用来计算多项式的结果 
int A[103],key[1000003];
//A[]记录式中的a0,a1,a2(注意是以0为起点)
//key记录每个解的值 
ll read(){//读入优化(似乎不加会T两个点w)
    ll sum=0,fg=1;
    char c=getchar();
    while(c < '0' || c > '9'){
        if(c=='-') fg=-1;//如果读到负号则记录 
        c=getchar();
    }
    while(c >='0' && c <='9'){
        sum=((sum*10)+c-'0')%p;
        //注意因为A[]可能很大,所以读入时就要进行取模操作 
        c=getchar();
    }
    return sum*fg;
    //如果是负数(fg==-1,即读到了负号)那么返回的值为负数 
}
void print(int x){//输出优化(这个可以不加)
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9){
        print(x/10);
    }
    putchar(x%10+'0');
}
bool calc(ll x){
    sum=0;//一定要清零!!!
    for(ll i=n;i>=0;i--){
        sum=((A[i]+sum)*x)%p;
        //这里套用秦九韶算法求多项式的值 
    }
    return !sum;//如果答案是0说明x值为该多项式的解,返回1(true) 
}
int main(){
    n=read();
    m=read();
    for(ll i=0;i<=n;i++){
        A[i]=read();
    }
    for(ll i=1;i<=m;i++){
        if(calc(i)){//如果返回的是1(true)则说明有解 

            t=false; 
            ans++;//记录答案个数 
            key[++cnt]=i;//记录每个解的值 
        }
    }
    if(t){
        cout<<ans<<endl;//如果t未改变则说明解的个数为0 
        return 0;
    }
    print(ans);
    printf("\n");
    for(ll i=1;i<=cnt;i++){
        print(key[i]);
        printf("\n");
    }
    return 0;
}

然后呢算法时间复杂度大概是O(n*m),这样子这道题就A掉了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值