• bzoj 3751: [NOIP2014]解方程


    Description

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

    解题报告:

    这题比较诡,看到高精度做不了,就要想到取模,然后很容易发现是有问题的,所以要多取几个增加正确性,然后就开始枚举解,对于合法的解一定是对所有你选的质数都成立。
    对于求这个多项式的值可以用秦九韶算法,这里不多做赘述.

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=105,M=1000005;
    int pri[6]={30011,11261,14843,19997,10007,21893},n,m,a[N][6];
    bool vis[M/10][6];
    void gi(int i){
       char ch=getchar();int f=1;
       while(ch>'9' || ch<'0'){
          if(ch=='-')f=-1;ch=getchar();
       }
       while(ch>='0' && ch<='9'){
          for(int k=0;k<6;k++)
             a[i][k]=a[i][k]*10+ch-48,a[i][k]%=pri[k];
          ch=getchar();
       }
       for(int k=0;k<6;k++)a[i][k]*=f;
    }
    int ans[M],num=0;
    bool judge(int x,int k){
       int ret=0;
       for(int i=n;i>=1;i--)
          ret=x*ret%pri[k]+a[i][k],ret%=pri[k];
       return ret==0;
    }
    bool check(int x){
       for(int i=0;i<6;i++)
          if(vis[x%pri[i]][i]==0)return false;
       return true;
    }
    void work()
    {
       scanf("%d%d",&n,&m);n++;
       for(int i=1;i<=n;i++)gi(i);
       for(int i=0;i<6;i++)
          for(int j=0;j<pri[i];j++)
             vis[j][i]=judge(j,i);
       for(int i=1;i<=m;i++)
          if(check(i))ans[++num]=i;
       printf("%d
    ",num);
       for(int i=1;i<=num;i++)printf("%d
    ",ans[i]);
    }
    
    int main(){work();return 0;}
    
    
  • 相关阅读:
    .NET基础——数组
    .NET基础——循环、枚举
    .NET基础——运算符
    .NET基础——基本概念
    面向对象基础——结构体
    面向对象基础——静态成员、静态类
    面向对象基础——基本概念
    接口 与 抽象类
    委托与事件——事件
    委托与事件——委托
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7622164.html
Copyright © 2020-2023  润新知