zoukankan      html  css  js  c++  java
  • [NOIP2014]解方程 (暑假ACM1 H)

    题意

    求方程a0+a1x+a2x2+⋯anxn=0在[1,m]内的解。

    对于100% 的数据:0<n<=100,|ai|<=1010000,an≠0,m<1060

    题解

    当时是sxk大佬给我说的他的思路,因为题目有暗示  Hint:如果那是个模方程,求 (mod 10007)时 x%10007的各种解,那么我就会做了。

    所以他就说先对系数取模,然后求出[0,10006]的解,然后如果一个解是x0,那么(x0+10007)也是一个解,因为在将各种次方展开时,有10007系数的都模掉了,就变成了原方程。

    所以我看了看数据,ai怎么模?高精度???我问出了这个愚蠢的问题,可以利用快读边读入边取模,而且这个问题原来遇到过,我都忘了[菜鸡]

    不过我从一开始就产生了一种顾虑,就是就算是模方程,那左边计算不取模就可能爆掉,取模万一是10007的倍数最后得到0,不过这并不是一个正确解。

    还好这个是正确的,不然又打脸。

    后来又想到了取多个模数,并且想到了要用秦九韶算法,可是却跑偏了,因为要枚举[1,m]的数,就因为过不去,最后没敲。

    现在想想,其实挺简单的。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    const int mod1=10007;
    const int mod2=1000000007;
    const int maxm=1000005;
    int n,m;
    ll a[105],b[105];
    int ans[maxm];
    bool cx[10010];
    
    inline void read(int i){
        ll x=0,y=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)){x=x*10%mod1+ch-'0';y=y*10%mod2+ch-'0';ch=getchar();}
        if(f) x=-x,y=-y;
        a[i]=x;b[i]=y;
    }
    
    bool nice(ll x){
        ll ret=0;
        for(int i=n;~i;i--)
         ret=(ret*x+a[i])%mod1;
        return !ret;
    }
    
    bool sto324(ll x){
        ll ret=0;
        for(int i=n;~i;i--)
         ret=(ret*x+b[i])%mod2;
        return !ret;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++) read(i);
        //for(int i=0;i<=n;i++) printf("%d %d
    ",a[i],b[i]);
        for(int i=0;i<mod1;i++)
         if(nice(i)) 
          cx[i]=true;
        for(int i=1;i<=m;i++)
         if(cx[i%mod1]&&sto324(i))
          ans[++ans[0]]=i;
        for(int i=0;i<=ans[0];i++)
         printf("%d
    ",ans[i]);
    }
    View Code
  • 相关阅读:
    01人月神话阅读笔记
    第一阶段冲刺010
    03构建之法阅读笔记
    第一阶段冲刺09
    第一阶段冲刺08
    第一阶段冲刺07
    第一阶段冲刺06
    08返回一个整数数组中最大子数组的和
    02构建之法阅读笔记
    请给出一个Scala RDD的HelloWorld例子
  • 原文地址:https://www.cnblogs.com/sto324/p/11222754.html
Copyright © 2011-2022 走看看