解方程 2014NOIP提高组 (数学)
解方程
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述 Description
输入描述 Input Description
输入文件名为equation.in。
输入共n+2行。
第一行包含2个整数n、m,每两个整数之间用一个空格隔开。
接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an。
输出描述 Output Description
输出文件名为equation.out。
第一行输出方程在[1, m]内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
样例输入 Sample Input
equation.in |
equation.out |
2 10 1 -2 1
|
1 1 |
equation.in |
equation.out |
2 10 2 -3 1
|
2 1 2 |
样例输出 Sample Output
equation.in |
equation.out |
2 10 1 3 2
|
0 |
数据范围及提示 Data Size & Hint
/* 将每一项的系数都模一个质数, 若一个数是方程的解,那么在模的意义下它也是方程的解(但反过来不一定)。 为了解决这个“不一定”的问题,多选几个质数, 若一个数在不同模的意义下都是方程的解,那么它有极大的几率就是原方程的解了。 */ #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<vector> using namespace std; const int mod[8]= {0,13,7901,3947,131,6977,22877,49997}; char s[105][1000010]; int n,m; int num[9][120]; bool solve(int od,int x) { int i,j; long long tmp=0; long long pw=1; for(i=0; i<=n; ++i) { if(s[i][0]=='-') tmp=(tmp-pw*num[od][i])%mod[od]; else tmp=(tmp+pw*num[od][i])%mod[od]; pw=pw*x%mod[od]; } while(tmp<0) tmp+=mod[od]; if(!tmp)return true; return false; } int res[1000010]; int ans[1000010],act=0; int main() { int i,j,k; scanf("%d%d",&n,&m); for(i=0; i<=n; ++i) scanf("%s",s[i]); int len[101]; for(i=0; i<=n; ++i)len[i]=strlen(s[i]); for(k=1; k<=7; ++k) for(i=0; i<=n; ++i) { for(j=0; j<len[i]; ++j) { if(s[i][j]=='-')continue; num[k][i]=num[k][i]*10+s[i][j]-'0'; num[k][i]%=mod[k]; } } for(k=1;k<=7;++k) for(i=0; i<mod[k] && i<=m; ++i) { if(!solve(k,i))continue; ++res[i]; for(j=i+mod[k]; j<=m; j+=mod[k]) { res[j]++; } } for(i=1; i<=m; ++i) if(res[i]==7)ans[++act]=i; printf("%d\n",act); for(i=1; i<=act; ++i)printf("%d\n",ans[i]); return 0; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。