1. 程式人生 > >jzoj3935. 【NOIP2014day2官方資料】解方程

jzoj3935. 【NOIP2014day2官方資料】解方程

問題描述

在這裡插入圖片描述
在這裡插入圖片描述

70%

因為數字太大搞不了,所以考慮處理每個數取模後的值
每次列舉x,判斷x是否在模意義下成立

當然這樣做無法保證正確性,所以考慮用多模數來做
70%的話只需要取998244353和1000000007就夠了
時間複雜度:O(Tnm)O(Tnm) (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; }