题目描述
已知多项式方程:
求这个方程在[1, m ] 内的整数解(n 和m 均为正整数)
输入输出格式
输入格式:
输入文件名为equation .in。
输入共n + 2 行。
第一行包含2 个整数n 、m ,每两个整数之间用一个空格隔开。
接下来的n+1 行每行包含一个整数,依次为a0,a1,a2..an
输出格式:
输出文件名为equation .out 。
第一行输出方程在[1, m ] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m ] 内的一个整数解。
输入输出样例
输入样例:
2 10
2
-3
1
输出样例:
2
1
2
题解
又来发bzoj水题题解了。。
30分思路:解一元二次方程,你懂得
50分思路:高精暴力
70分思路:依然是暴力,但结果要膜一个大质数(10000左右)多试几次。
100分思路:当x大于要膜的质数k时,结果和带入x%k是等价的,只需从1-k暴力枚举即可。
总体就4个字:暴力、人品。
为什么要人品呢?因为你膜的质数正好全碰上了wa的质数就蛤蛤了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,l,cnt=0;
int a[6][101],pd[6][40005],ans[1000005];
char st[10086];
const int modz[6]={30011,11261,14843,19997,10007,21893};//bzoj上发现的ac质数
int mod(int k,int x,int y) {
int flag=1;
a[x][y]=0;
int p=0;
if (st[p]=='-'){
p++;
flag=-1;
}
if (st[p]=='+')p++;
while(p<l) {
a[x][y]=(a[x][y]*10+st[p]-'0')%k;
p++;
}
a[x][y]=(a[x][y]*flag)%k;
if(a[x][y]<0)a[x][y]+=k;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=0;i<=n; i++) {
memset(st,0,sizeof(st));
scanf("%s",&st);
l=strlen(st);
for(int j=0; j<=5; j++) {
mod(modz[j],j,i);
}
}
memset(pd,0,sizeof(pd));
for(int i=0;i<=5;i++){
for(int j=0;j<=modz[i];j++){
int res=0;
for(int k=n;k>=0;k--){
res=res*j+a[i][k];
res%=modz[i];
}
if(res!=0)pd[i][j]=1;
}
}
memset(ans,0,sizeof(0));
for(int i=1;i<=m;i++){
for(int j=0;j<=5;j++){
if(pd[j][i%modz[j]]==1){
ans[i]=1;
break;
}
}
if(ans[i]==0)cnt++;
if(cnt>=n)break;
}
printf("%d\n",cnt);
for(int i=1;i<=m;i++){
if(ans[i]==0)printf("%d\n",i),cnt--;
if(cnt==0)break;
}
return 0;
}