• UOJ20 解方程


    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

    Description

     已知多项式方程:

    a0+a1*x+a2*x^2+...+an*x^n=0
    求这个方程在[1,m]内的整数解(n和m均为正整数)。
     

    Input

    第一行包含2个整数n、m,每两个整数之间用一个空格隔开。
    接下来的n+1行每行包含一个整数,依次为a0,a1,a2,...,an。

    Output

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

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

    Sample Input

    2 10
    2
    -3
    1

    Sample Output

    2
    1
    2

    HINT 

     对于100%的数据,0<n≤100,|ai|≤1010000,an≠0,m≤1000000。

    正解:模意义下相等

    解题报告:

      这道题的画风可以说是NOIP的day2T3中最奇怪的了,算法简单,只是谁想得到联赛T3考这种题目...

      首先可以明确,假设本来某个x就成立,那么我把系数和x的次幂都取一个模,这个式子同样成立。所以考虑取几个模数,然后对于式子整体取模,并且检验,如果都等于0我们就可以视为原式相等。

      但是这个做法只有70分。考虑如何优化,因为如果x大于模数,那么可以发现x+p再代入原式,得到的答案没有任何区别,所以我们可以把模数取小一点,为了保证正确率,模数取多一点,然后我们只对于每个模数检验0到模数-1,因为大了就没有意义了。这样的做法可以获得100分。但是模数要取得好,我试了很久,发现最少要取3个,少了就肯定会错了...

     
     1 //It is made by ljh2000
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 using namespace std;
    14 typedef long long LL;
    15 #define RG register
    16 const int MAXN = 50011;
    17 int n,m,len,pcnt=2,prime[12]={23333,22877,19997};
    18 int a[12][MAXN],now_ans,xx,ss,ans[12][MAXN],cnt,dui[1000011];
    19 char ch[10011];
    20 bool fu[150];
    21 
    22 inline int getint()
    23 {
    24     int w=0,q=0; char c=getchar();
    25     while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
    26     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
    27 }
    28 
    29 inline bool check(RG int x){
    30     for(RG int i=0;i<=pcnt;i++)
    31     if(ans[i][x%prime[i]]!=0)  return false;
    32     return true;
    33 }
    34 
    35 inline void work(){
    36     n=getint(); m=getint(); 
    37     for(RG int i=0;i<=n;i++) {//读入第i个系数
    38     scanf("%s",ch); len=strlen(ch); if(ch[0]=='-') fu[i]=1;
    39     for(RG int o=0;o<=pcnt;o++) {//分别求出对于每个模数意义下的系数的实际值
    40         ss=1;
    41         for(RG int j=len-1;j>=1;j--) {          
    42         a[o][i]+=(ch[j]-'0')*ss; a[o][i]%=prime[o];
    43         ss*=10; ss%=prime[o];
    44         }        
    45         if(fu[i]==0) { a[o][i]+=(ch[0]-'0')*ss; a[o][i]%=prime[o]; ss*=10; ss%=prime[o]; }
    46     }
    47     }
    48     for(RG int i=0;i<=pcnt;i++) {
    49     for(RG int x=0;x<prime[i];x++) {        
    50         xx=1; now_ans=0;
    51         for(RG int j=0;j<=n;j++) {        
    52         if(fu[j]) now_ans-=xx*a[i][j]; else now_ans+=xx*a[i][j]; 
    53         now_ans%=prime[i];       
    54         xx*=x; xx%=prime[i];
    55         }
    56         ans[i][x]=now_ans;
    57     }
    58     }
    59     for(RG int i=1;i<=m;i++) if(check(i)) dui[++cnt]=i;
    60     printf("%d
    ",cnt);
    61     for(RG int i=1;i<=cnt;i++) printf("%d
    ",dui[i]);
    62 }
    63 
    64 int main()
    65 {
    66     work();
    67     return 0;
    68 }
  • 相关阅读:
    日报10.29
    日报10.28
    日报10.27
    周进度总结-6
    日报10.25
    日报10.23
    日报10.22
    日报10.21
    日报10.18
    STL bitset
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6059188.html
Copyright © 2020-2023  润新知