jzoj3935. 【NOIP2014day2官方資料】解方程
阿新 • • 發佈:2019-02-04
問題描述
70%
因為數字太大搞不了,所以考慮處理每個數取模後的值
每次列舉x,判斷x是否在模意義下成立
當然這樣做無法保證正確性,所以考慮用多模數來做
70%的話只需要取998244353和1000000007就夠了
時間複雜度: (T是模數個數)
80%
把原多項式變成遞推,每次找到一個xi後就用原多項式去除(x-xi)
這樣可以水到80分當然加個O3說不定更高
100%
顯然x在模p意義下是,x和x+kp的值相同
所以對於每個模數,只需要列舉0~p-1就可以知道剩下的結果了
如果一個數在所有模數意義下都為0,那麼這個數就可能是答案
為了保證正確性,同時為了避免longlong和減小時間複雜度,10個4萬左右的模數就夠了
具體可以看標
code
#include <iostream>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define N 10
using namespace std;
int hash[N+1]={0,40009,40013,40031,40037,40039,40063,40087,40093,40099,40111};
int a[N+1][101];
int n,m,i,j,k,l,tot,x,sum;
int bz[1000001];
char ch;
bool Bz;
int main()
{
scanf("%d%d\n",&n,&m);
fo(i,0,n)
{
ch=getchar();
if (ch=='-')
Bz=1;
else
{
Bz=0;
fo(j,1,N)
a[j][i]=ch-'0';
}
ch=getchar();
while (ch!='\n')
{
fo(j,1,N)
a[j][i]=(a[j][i]*10+(ch-'0'))%hash[j];
ch=getchar();
}
if (Bz)
{
fo( j,1,N)
a[j][i]=(hash[j]-a[j][i])%hash[j];
}
}
fo(j,1,N)
{
fo(x,0,hash[j]-1)
{
sum=0;
fd(i,n,0)
sum=(sum*x+a[j][i])%hash[j];
if (!sum)
{
k=x;
while (k<=m)
{
bz[k]++;
k+=hash[j];
}
}
}
}
fo(i,1,m)
if (bz[i]==N)
tot++;
printf("%d\n",tot);
fo(i,1,m)
if (bz[i]==N)
printf("%d\n",i);
return 0;
}