Noip 2014 senior Day2 解方程(equation)

Noip 2014 senior Day2 解方程(equation)

【问题描述】

已知多项式方程:

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

【输入】

输入文件名为 equation.in。

输入共 n+2 行。

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

接下来的 n+1 行,每行包含一个整数, 依次为。

【输出】

输出文件名为 equation.out。

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

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

【输入输出样例 1】

equation.in                                                                         equation.out

2 10                                                                                     1

1                                                                                          1

-2

1

【输入输出样例 2】

2 10                                                                                      1

2                                                                                           2

-3                                                                                          1

1

【输入输出样例 3】

2 10                                                                                      0

1

3

2

       这道题的话,用同余来想一下就好了。如果原方程成立,那么方程两边同时modp,方程依然成立(显然)。若f(x) ≡0(mod p)则f(x+p) ≡ 0(mod p)。这些都应该是比较好想的对吧。所以我可想到这样来解决:选几个大质数,首先预处理出1-(P-1)代入方程在模P意义下的结果。然后我们枚举解。每次用这几个大质数检验一下即可。

       这样一来是不是思路就清晰了。

       比较需要注意的是对于高精度的使用,可以选择使用李兄一贯的写在struct里面(但是上次我写错了),也可以就选则使用数组来保存。对于每一个读入的我们首先对它modp然后再存入数组。代入求解什么的就不需要再说了吧。

  

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define N 10010
  6 #define M 1000010
  7 using namespace std;
  8 
  9 const int pri[10] = {11261,23333,10007,21893,14843};
 10 
 11 inline long long read(){ 
 12     long long data=0,w=1; 
 13     char ch=0; 
 14     while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar(); 
 15     if(ch=='-') w=-1,ch=getchar(); 
 16     while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); 
 17     return data*w;
 18 }
 19 
 20 inline void write(long long x)
 21 {
 22      if(x<0) putchar('-'),x=-x;
 23      if(x>9) write(x/10);
 24      putchar(x%10+'0');
 25 }
 26 
 27 int n,m;
 28 int lenth;
 29 int ans[M],a[10][N],aider[10][N],wo[10][N * 5];
 30 char str[N];
 31 
 32 inline int work(int x)
 33 {
 34     int temporary = 0;
 35     for(int i=0;i<=n;i++)
 36     {
 37 //        temporary += a[x][i] * aider[x][i];
 38 //        temporary %= pri[x];
 39         (temporary += a[x][i] * aider[x][i]) %= pri[x];
 40     }
 41     if(temporary < 0) temporary += pri[x];
 42     return temporary;
 43 }
 44 
 45 inline bool check(int x)
 46 {
 47     for(int i=0;i<=4;i++) if(wo[i][x%pri[i]] != 0) return false;
 48     return true;
 49 }
 50 
 51 int main()
 52 {
 53     freopen("equation.in","r",stdin);
 54     freopen("equation.out","w",stdout);
 55     
 56     n = read();
 57     m = read();
 58     for(int i=0;i<=n;i++)
 59     {
 60         scanf("%s",str+1);
 61         bool flag = true;
 62         lenth = strlen(str+1);
 63         for(int j=0;j<=4;j++) // 该数 mod p[j]下的结果 
 64         {
 65             if (str[1] != '-') a[j][i] = str[1] - '0';
 66             else flag = false;
 67             for(int k=2;k<=lenth; k++)
 68             {
 69 //                a[j][i] = a[j][i] * 10 + str[k];
 70 //                a[j][i] %= pri[j];
 71                 (a[j][i] = a[j][i] * 10 + str[k] - '0') %= pri[j];
 72             }
 73             if(!flag) a[j][i] = -a[j][i];
 74         }
 75     }
 76     for(int i=0;i<=4;i++)
 77     {
 78         for(int j=1;j<=pri[i]-1;j++) // 预处理大素数之前的所有数代入方程后 mod pri[i]的结果 
 79         {
 80              aider[i][0] = 1;
 81              for(int k=1;k<=n;k++)
 82              {
 83 //                 aider[i][k] = aider[i][k-1] * j;
 84 //                 aider[i][k] %= pri[i];
 85                  (aider[i][k] = aider[i][k-1] * j) %= pri[i];
 86              }
 87              wo[i][j] = work(i);
 88         }
 89     }
 90     for(int i=1;i<=m;i++)
 91     {
 92         if(check(i)) ans[++ans[0]] = i;
 93     }
 94     write(ans[0]);
 95     putchar('
');
 96     for(int i=1;i<=ans[0];i++)
 97     {
 98         write(ans[i]);
 99         putchar('
');
100     }
101     
102     return 0;
103 }
104 /*
105 若f(x) ≡0(mod p)则f(x+p) ≡0(mod p);
106 若原方程成立。那么在方程两边同时模P,方程仍然成立。
107 所以我们可以选几个大质数,首先预处理出1-(P-1)代入方程在模P意义下的结果。
108 然后我们枚举解。每次用这几个大质数检验一下即可。
109 */
原文地址:https://www.cnblogs.com/sin-mo/p/7191814.html