已知多項式方程:ios
\[a_0+a_1x+a_2x^2+⋯+a_nx^n=0\]數組
求這個方程在 [1,m] 內的整數解(n 和 m均爲正整數)。spa
輸入格式:code
共 n+2行。ci
第一行包含 2 個整數 n,m,每兩個整數之間用一個空格隔開。string
接下來的 n+1行每行包含一個整數,依次爲 a0,a1,a2…an。io
輸出格式:class
第一行輸出方程在 [1,m] 內的整數解的個數。stream
接下來每行一個整數,按照從小到大的順序依次輸出方程在 [1,m] 內的一個整數解。im
輸入樣例#1:
2 10
1
-2
1
輸出樣例#1:
1
1
輸入樣例#2:
2 10
2
-3
1
輸出樣例#2:
2
1
2
輸入樣例#3:
2 10
1
3
2
輸出樣例#3:
0
對於 30% 的數據:\(0<n≤2,∣a_i∣≤100,a_n≠0,m<100\).
對於 50% 的數據:\(0<n≤100,∣a_i∣≤10^{100},a_n≠0,m<100\)。
對於 70% 的數據:\(0<n≤100,∣a_i∣≤10^{10000},a_n≠0,m<10^4\)。
對於 100% 的數據:\(0<n≤100,∣a_i∣≤10^{10000},a_n≠0,m<10^6\)。
首先咱們得明白一條性質,若是咱們選一個質數p,若是枚舉x,發現多項式結果ans%p≠0,那麼咱們就能確定x不是解,由於若是是解,那麼多項式答案應該爲0,可是0模任何數(除0以外)都爲0,而此時發現模p不等於0,那麼顯然x不是解,看一波複雜度,O(NM)貌似能夠過70分。繼續想,
既然x不是解那麼顯然x+p也不是解,這樣問題就解決了。
prime[i],表明第i個質數是什麼。
可是又不能枚舉去篩,那複雜度又上去了,因此能夠用數組存下來,\(vis[i][j]\)表明i這個數取模第j個質數不等於0,那麼到時枚舉解x時,只需判斷\(vis[x~~mod ~~prime[j]][j]\)是否等於0就好了,爲了怕出錯,多選幾個質數就好了。
本題數據範圍這麼大,有點操蛋,這是要寫高精度的節奏,死活不打。
發現能夠一邊讀入一邊取模。
這題數據有點強,卡1~200全部質數,因此我就選了一千多的質數。
代碼:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef unsigned long long ll; char s[101][10010]; ll prime[]={2,7,9,11,103,1597,1601,1607,1609,1613,1619,1621,1627}; ll real[1010000],kzj=0; ll p[110][20],vis[120][20]; ll ans[1001010]; ll check(char *ss,ll mod) { ll flag=1,tot=0,x=0;char ch=ss[0]; ll len=strlen(ss); if(ch<'0'||ch>'9') if(ch=='-') flag=-1,tot++,ch=ss[1]; while(ch<='9'&&ch>='0') { x=((x*10)%mod+(ch-48))%mod; ch=ss[++tot]; if(tot==len) break; } return (x*flag+mod)%mod; } int main() { // freopen("xuanxue.in","r",stdin); // freopen("xuanxue.out","w",stdout); ll n,m; cin>>n>>m; n++; for(ll i=1;i<=n;i++) scanf("%s",s[i]); for(ll i=1;i<=n;i++) { for(ll j=0;j<=12;j++) p[i][j]=check(s[i],prime[j]); } for(ll i=1;i<=1700;i++) { ll flag=0; for(ll j=0;j<=12;j++) { ll k=1,sum=0; ll mod=prime[j]; for(ll t=1;t<=n;t++) { sum=(sum%mod+p[t][j]%mod*k%mod)%mod; k=k*i%mod; } if(sum!=0) { vis[i][j]=1; } } } for(ll i=1;i<=m;i++) { ll flag=0; for(ll j=0;j<=12;j++) if(vis[i%prime[j]][j]==1) flag=1; if(!flag) real[++kzj]=i; } cout<<kzj<<endl; for(ll i=1;i<=kzj;i++) printf("%lld\n",real[i]); }