zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    LSMW TIPS
    Schedule agreement and Delfor
    Running VL10 in the background 13 Oct
    analyse idoc by creation date
    New Journey Prepare
    EDI error
    CBSN NEWS
    Listen and Write 18th Feb 2019
    Microsoft iSCSI Software Target 快照管理
    通过 Microsoft iSCSI Software Target 提供存储服务
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6059188.html
Copyright © 2011-2022 走看看