vijos1910解方程

 

描述

已知多项式方程:

a0+a1x+a2x2+...+anxn=0a0+a1x+a2x2+...+anxn=0

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

格式

输入格式

输入共 n+2 行。

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

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

输出格式

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

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

样例1

样例输入1[复制]

 
2 10
1
-2
1

样例输出1[复制]

 
1
1

样例2

样例输入2[复制]

 
2 10
2
-3
1

样例输出2[复制]

 
2
1
2

样例3

样例输入3[复制]

 
2 10
1
3
2

样例输出3[复制]

 
0

限制

对于 30%的数据,0 < n ≤ 2, |ai||ai| ≤ 100,anan ≠ 0, m ≤ 100;

对于 50%的数据,0 < n ≤ 100, |ai||ai| ≤ 1010010100 ,anan ≠ 0,m ≤ 100;

对于 70%的数据,0 < n ≤ 100, |ai||ai| ≤ 10100001010000 ,anan ≠ 0,m ≤ 10000;

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

来源

NOIP2014 提高组 Day2


 

初看本题,知道要取模一个素数但是有两个地方没考虑

1一个素数不够用,可能要出错,用5个素数就差不多了,这五个素数可以比较小10^4级就可以了

2根据题意如果f(x)=0,那么f(x+p)=0,后面的就不用算了

AC代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #define M 1000002
 4 #define N 102
 5 using namespace std;
 6 int n,m;
 7 int ans[M];
 8 int a[N][5];
 9 int t[205][5];
10 int c[25000][5];
11 int p[5]={10007,23333,11119,11777,11177};
12 int cal(int y)
13 {
14     int tmp=0;
15     for(int i=0;i<=n;i++)
16     tmp=(tmp+a[i][y]*t[i][y])%p[y];
17     if(tmp<0)//减法取余要注意可能减到负数 
18         tmp+=p[y];
19     return tmp;
20 }
21 bool check(int mm)
22 {
23     for(int i=0;i<5;i++)
24     if(c[mm%p[i]][i]!=0)
25     return false;
26     return true;
27 }
28 int main()
29 {
30     cin>>n>>m;
31     for(int i=0;i<=n;i++)//读大系数 
32     {
33         char ai[10005];
34         scanf("%s",ai);
35         for(int k=0;k<5;k++)
36         {
37             int factor=0;
38             int j=0;
39             if(ai[0]=='-')j++;
40             for(;;j++)
41             {
42                 if(ai[j]<='9'&&ai[j]>='0')
43                 factor=(factor*10+ai[j]-'0')%p[k];
44                 else break;
45             }
46             if(ai[0]=='-')
47             factor*=-1;
48             a[i][k]=factor;
49         }
50     }
51     for(int i=0;i<5;i++)
52     for(int j=1;j<=p[i];j++)
53     {
54         t[0][i]=1;//第一个系数为a0*x^0
55         for(int k=1;k<=n;k++)t[k][i]=(t[k-1][i]*j)%p[i];
56         c[j][i]=cal(i);
57     }
58     for(int i=1;i<=m;i++)
59     if(check(i))
60     ans[++ans[0]]=i;
61     cout<<ans[0]<<endl;
62     for(int i=1;i<=ans[0];i++)
63     printf("%d\n",ans[i]);
64     return 0;
65 }

 

转载于:https://www.cnblogs.com/lwhinlearning/p/5697784.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值