P2312 解方程
题意:给出一个方程$a_0+a_1x+a_2x^2+...+a_nx^n=0$的系数所有系数$a_i$,求方程在$[1,m]$内的整数解
数据范围:
对于 30% 的数据:$0<n\le 2,|a_i|\le 100,a_n≠0,m<100$
对于 50% 的数据:$0<n\le 100,|a_i|\le 10^{100},a_n≠0,m<100$
对于 70% 的数据:$0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^4$
对于 100% 的数据:$0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^6$
看到瞬间。。。暴力高精。。。
但是x的次幂怎么处理?
有个叫秦九韶的大佬(瞎BB)
注意系数的符号
所以在高精数组里记录了一个fu
在加法时候判断一下
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double struct node { int mp[50505]; int len; int fu; node () { memset(mp,0,sizeof mp); len=1; fu=1; } int &operator [] (int a) { return mp[a]; } friend bool operator < (const node &a,const node &b) { if(a.len<b.len) return true; if(a.len>b.len) return false; for(int i=a.len;i>=1;i--) { if(a.mp[i]<b.mp[i]) return true; if(a.mp[i]>b.mp[i]) return false; } return true; } friend node operator + (const node &a,const node &b) { node t; t.len=max(a.len,b.len)+2; if(a.fu==b.fu) { for(int i=1;i<=t.len;i++) { t.mp[i]+=a.mp[i]+b.mp[i]; t.mp[i+1]+=t.mp[i]/10; t.mp[i]%=10; } while(t.len>1&&t.mp[t.len]==0) t.len--; t.fu=a.fu; } if(a.fu!=b.fu) { if(b<a) { t.len=max(a.len,b.len); for(int i=1;i<=t.len;i++) { t.mp[i]+=a.mp[i]-b.mp[i]; if(t.mp[i]<0) { t.mp[i]+=10; t.mp[i+1]--; } } t.fu=a.fu; } else { t.len=max(a.len,b.len); for(int i=1;i<=t.len;i++) { t.mp[i]+=b.mp[i]-a.mp[i]; if(t.mp[i]<0) { t.mp[i]+=10; t.mp[i+1]--; } } t.fu=b.fu; } while(t.len>1&&t.mp[t.len]==0) t.len--; } return t; } void out() { if(fu==-1) putchar('-'); for(int i=len;i>=1;i--) putchar(mp[i]+'0'); } friend node operator * (const node &a,const node &b) { node t; t.len=a.len+b.len+2; for(int i=1;i<=a.len;i++) for(int j=1;j<=b.len;j++) { t.mp[i+j-1]+=a.mp[i]*b.mp[j]; t.mp[i+j]+=t.mp[i+j-1]/10; t.mp[i+j-1]%=10; } while(t.len>1&&t.mp[t.len]==0) t.len--; t.fu=a.fu*b.fu; return t; } void copy(const node &a) { len=a.len; for(int i=1;i<=len;i++) mp[i]=a.mp[len-i+1]; } }; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } int n; int m; int tot; node a[150]; int ans[1050500]; inline bool ok(int xx) { node x; x.len=0; while(xx) { x[++x.len]=xx%10; xx/=10; } node t; t=a[n]; for(int i=n;i>=1;i--) { t=t*x+a[i-1]; } if(t.len==1&&t[t.len]==0) return true; return false; } signed main() { n=read(); m=read(); for(int i=0;i<=n;i++) { int f=1; node ls; ls.len=0; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { ls[++ls.len]=ch^48; ch=getchar(); } a[i].copy(ls); a[i].fu=f; } for(int i=1;i<=m;i++) { if(ok(i)) ans[++tot]=i; } put(tot); putchar('\n'); for(int i=1;i<=tot;i++) { put(ans[i]); putchar('\n'); } olinr ~~(0^_^0)+love_nmr; }
然而这数据范围是承受不了的。。。。$O(n*m*高精)$
光是$n*m$就已经$10^8$了QAQ
所以,有个niubilitiful的东西--------取模啊
模一个大质数!
注意输入用快读
快读一边读一边模6666666
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double const int mod=1000000007LL; int a[150]; int ans[1050000]; int tot; int n; int m; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); x%=mod; ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } inline bool ok(int x) { int t=a[n]; for(int i=n;i>=1;i--) t=(t*x+a[i-1])%mod; if(t==0) return true; return false; } signed main() { n=read(); m=read(); for(int i=0;i<=n;i++) { a[i]=read(); a[i]%=mod; } for(int i=1;i<=m;i++) { if(ok(i)) ans[++tot]=i; } put(tot); putchar('\n'); for(int i=1;i<=tot;i++) { put(ans[i]); putchar('\n'); } olinr ~~(0^_^0)+love_nmr; }
注意,在秦九韶的时候,少取模!!会TLE
因为取模和除法一样,要调用系统库,(不信可以GDB单步执行)
速度自然慢了
原来用了5个取模
TLE3个点
减少了2个,居然快了400多msQAQ
索性在int之内减少更多
----olinr