【NOIP2014提高组】解方程
题目传送门:https://www.luogu.org/problem/show?pid=2312 (习惯性放洛谷的链接)
这一题看起来数据范围巨大无比,需要使用各种玄学方法,看了题解后整个人懵逼了....
对于30%的数据,0<n≤2,|ai|≤100,an!=0,m<100。
该数据范围直接高精度,在[1,m]的范围内暴力枚举即可。时间复杂度为O(n∗m∗len2),其中len表示高精度计算过程中数字的位数。
对于50%的数据:0<n<=100,|ai|<=10100,an≠0,m<100。
我们考虑用秦九昭算法对计算进行加速,秦九昭算法思路如图:
该算法目的为在求一元n次多项式的值时,将求值需要经过n2次乘法和n次加法降低至n次乘法和n次加法。
通过此方法化简,时间复杂度被降低一个len。即可拿到50分。
对于100%的数据:0<n⩽100,|ai|⩽1010000,an≠0,m<1000000。
我们考虑将高精度的过程去掉。
考虑到同余的某些性质,我们可以对方程的两边对p取模(p为质数),若x满足(∑n0aixi)=0,则其必然满足∑n0aixi ≡ 0 (mod p)。
根据同余性质,可将其进一步化简为∑n0(aiximodp)≡0(modp),借助该方法,在枚举x值的过程中便不需要使用高精度计算了。
如果逆着推上面的式子,会发现存在有x,使得∑n0(aiximodp)≡0(modp),但(∑n0aixi)≠0。为了避免推出不可行解,首先p尽可能地取大,其次是多选几个p分别进行取模,降低通过逆定理求出错误的x的概率(我比较懒只对一个大质数取模,结果过掉了)
1 #include<bits/stdc++.h> 2 #define M 2000000 3 #define MOD 100000007 4 #define L long long 5 using namespace std; 6 L rd(){ 7 int zf=1; char c; L k=0; 8 for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') zf=-1; 9 for(;isdigit(c);c=getchar()) k=(k*10+c-'0')%MOD; 10 return k*zf; 11 } 12 L a[M]={0},n,m,p[M]={0},ans=0; 13 bool check(int x){ 14 L sum=0; 15 for(int i=n;i>=0;i--) 16 sum=(a[i]+sum+MOD)*x%MOD; 17 return sum==0; 18 } 19 int main(){ 20 cin>>n>>m; 21 for(int i=0;i<=n;i++) a[i]=rd(); 22 for(int i=1;i<=m;i++) if(check(i)){ 23 ans++; p[i]=1; 24 } 25 printf("%d\n",ans); 26 for(int i=1;i<=m;i++) if(p[i]) 27 printf("%d\n",i); 28 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!