版权声明:欢迎转载,请注明出处,谢谢 https://blog.csdn.net/Dream_maker_yk/article/details/82666693
LOJ2503 NOIP2014 解方程
题目大意就是给你一个方程,让你求 中的解,其中系数非常大
看到是提高T3还是解方程就以为是神仙数学题
后来研究了一下高精之类的算法发现过不了多少分
后面佬说这题是hash
然后就雾
考虑对于一个式子
肯定会满足
所以我们直接多取几个相近的prime,减小冲突几率
然后我们只需要预处理每个系数对于每个prime的模数,然后判断一下就可以了
但是这样会TLE
又可以发现对于任意的
,等价于
所以对于每个质数直接枚举比它小的数进行检查就好了
然后就比较和谐了
扫描二维码关注公众号,回复:
3258896 查看本文章
中间出了一些比较玄学的错误导致交了很多个70分
不过问题不大
#include<bits/stdc++.h>
using namespace std;
#define N 110
#define M 1000010
int prime[5]={10099,10103,10111,10133,10139};
int pa[N][5],n,m;
char c[M];
bool vis[M],ak[M][5];
int check(int x,int id){
int pic=0;
for(int i=n;i>=0;i--)
pic=(pic*x%prime[id]+pa[i][id])%prime[id];
return pic;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++){
scanf("%s",c);
int len=strlen(c),j=0;
if(c[0]=='-')j++;
for(;j<len;j++)for(int k=0;k<5;k++)
pa[i][k]=(pa[i][k]*10+c[j]-'0')%prime[k];
if(c[0]=='-')for(int k=0;k<5;k++)pa[i][k]*=-1;
}
int cnt=0;
for(int j=0;j<5;j++)
for(int i=0;i<prime[j];i++)
if(check(i,j)!=0)ak[i][j]=1;
for(int i=1;i<=m;i++){
bool can=1;
for(int j=0;j<5;j++)if(ak[i%prime[j]][j]){can=0;break;}
if(can)vis[i]=1,cnt++;
}
printf("%d\n",cnt);
for(int i=1;i<=m;i++)if(vis[i])printf("%d\n",i);
return 0;
}