• [BZOJ3751][NOIP2014]解方程(数学相关+乱搞)


    题目描述

    已知多项式方程:

    a0+a1x+a2x^2+..+anx^n=0

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

    输入输出格式

    输入格式:

    输入文件名为equation .in。

    输入共n + 2 行。

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

    接下来的n+1 行每行包含一个整数,依次为a0,a1,a2..an

    输出格式:

    输出文件名为equation .out 。

    第一行输出方程在[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<n<=2,|ai|<=100,an!=0,m<100

    对于50%的数据:0<n<=100,|ai|<=10^100,an!=0,m<100

    对于70%的数据:0<n<=100,|ai|<=10^10000,an!=0,m<10000

    对于100%的数据:0<n<=100,|ai|<=10^10000,an!=0,m<1000000

    题解:

      考试的时候取模数选的多还大无语了,然后总觉得不对。

      后来看了题解发现,我那样被严重卡常数。

      只需要取几个较小的模数,然后将式子左边取模,然后讲1-p(表示模数)

      每个模拟一次就是pn复杂度,然后看哪几个不为0,说明绝对不行,那么其倍数

      也不行,多选几个模数就可以了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 
     7 const int N=101;
     8 const int L=10010;
     9 const int M=1000010;
    10 const int TOT=4;
    11 
    12 int n,m,ans;
    13 int p[TOT+1],a[N],len[N];
    14 bool flg[M];
    15 char s[N][L];
    16 
    17 void make_list()
    18 {
    19     p[1]=22349;
    20     p[2]=22367;
    21     p[3]=22369;
    22     p[4]=17389;
    23 }
    24 int main()
    25 {
    26     make_list();
    27     scanf("%d%d",&n,&m);
    28     for(int i=0;i<=n;i++)
    29         scanf("%s",s[i]);
    30     for(int i=0;i<=n;i++)
    31         len[i]=strlen(s[i]);
    32     for(int i=1;i<=TOT;i++)
    33     {
    34         for(int j=0;j<=n;j++)
    35         {
    36             int flag=(s[j][0]=='-'?1:0);
    37             a[j]=0;
    38             for(int k=flag;k<len[j];k++)
    39                 a[j]=(a[j]*10+s[j][k]-'0')%p[i];
    40             if(flag) a[j]=-a[j];
    41         }//每个系数先取模 
    42         for(int j=1;j<=p[i];j++)
    43         {
    44             int tmp=0;
    45             for(int k=n;k>=0;k--)
    46                 tmp=(tmp*j+a[k])%p[i];
    47             if(tmp)//表示不行 
    48             for(int k=0;j+k*p[i]<=m;k++)
    49                 flg[j+k*p[i]]=1;//其倍数也不行 
    50         }
    51     }
    52     for(int i=1;i<=m;i++)
    53         if(!flg[i]) ans++;
    54     printf("%d
    ",ans);
    55     for(int i=1;i<=m;i++)
    56         if(!flg[i]) printf("%d
    ",i);
    57 }
  • 相关阅读:
    RocketMQ实战:生产环境中,autoCreateTopicEnable为什么不能设置为true
    x 的平方根--二分查找
    责任链模式--设计模式
    迭代器模式--设计模式
    组合模式--设计模式
    搜索旋转排序数组II
    搜索旋转排序数组--二分查找
    搜索插入位置--二分查找
    越狱详解与调试--逆向开发
    有序链表转换二叉搜索树--链表
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7747687.html
Copyright © 2020-2023  润新知