羅バレー(原題参照https://www.luogu.org/problem/show?pid=2312が)
QWQは
この事が作られた操作の数を減らすために使用することができ、多項式の値を計算する方法です-ホーナー法と呼ばれるものを持っているようだがホーナー法それのBaiduの百科事典を説明するために-それをTATリンクを知っている必要がありますが、これは、高校数学内容であることは、基本的には高校に行ってきました:( https://baike.baidu.com/item/ホーナー法/ 449196、FR =?アラジン)
この質問は〜私たちはああライン上でカウントするホーナー法により、多項式として左にそれを行うことができますです
inline bool qjs(long long x){
sum=0;
for(register int i=n;i>=0;i--){
sum=((a[i]+sum)*x)%p;
}
return !sum;
}
アイデアは1から1によって、次の1です〜メートル列挙値式は、限り、式の値が良い上の0カウントがあるとして、
最初にそれを説明するためのコードを掲載嘆きウ~~
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int p=1000000007;
long long a[110],key[1000000];
bool t=true;
int ans=0,cnt,sum=0;
int n,m;
inline long long read(){
long long sum=0,fg=1;
char c=getchar();
while(c<'0' || c>'9'){
if(c=='-'){
fg=-1;
}
c=getchar();
}
while(c>='0' && c<='9'){
sum=((sum*10)+c-'0')%p;
c=getchar();
}
return sum*fg;
}
inline void out(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9){
out(x/10);
}
putchar(x%10+'0');
}
inline bool qjs(long long x){
sum=0;//一定要清零
for(register int i=n;i>=0;i--){
sum=((a[i]+sum)*x)%p;
}
return !sum;
}
int main(){
n=read();
m=read();
for(register int i=0;i<=n;i++){
a[i]=read();
}
for(register int i=1;i<=m;i++){
if(qjs(i)){
t=false;
ans++;
cnt++;
key[cnt]=i;
}
}
if(t){
out(ans);
printf("\n");
return 0;
}
out(ans);
printf("\n");
for(register int i=1;i<=cnt;i++){
out(key[i]);
printf("\n");
}
return 0;
}
pは、我々はまた、映画を見て、爆発INTを防ぐために、大きな素数であり、最適化を読んで覚えることができる
機能が読み出され、高速なリードインとアウトプットの高速友人〜何その後、
BOOLトントンが解けるかどうかを決定するために使用されます。ソリューションは、レコード数にCNT。和多項式の結果を記録するために、我々はそうでない場合は10ポイントには、キー値の配列多項式係数は、の溶液のそれぞれの値を記録するために使用され、配列Aが記録されている、その合計がqjs機能をクリアする必要があります覚えておく必要があります
コピーを注釈付きのソリューション:
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int p=1000000007;//取模比较方便为
bool t=true;//用来判断是否有解
int n,m,ans,cnt,sum=0;//cnt记录解的个数;sum用来计算多项式的结果
int A[103],key[1000003];
//A[]记录式中的a0,a1,a2(注意是以0为起点)
//key记录每个解的值
ll read(){//读入优化(似乎不加会T两个点w)
ll sum=0,fg=1;
char c=getchar();
while(c < '0' || c > '9'){
if(c=='-') fg=-1;//如果读到负号则记录
c=getchar();
}
while(c >='0' && c <='9'){
sum=((sum*10)+c-'0')%p;
//注意因为A[]可能很大,所以读入时就要进行取模操作
c=getchar();
}
return sum*fg;
//如果是负数(fg==-1,即读到了负号)那么返回的值为负数
}
void print(int x){//输出优化(这个可以不加)
if(x<0){
putchar('-');
x=-x;
}
if(x>9){
print(x/10);
}
putchar(x%10+'0');
}
bool calc(ll x){
sum=0;//一定要清零!!!
for(ll i=n;i>=0;i--){
sum=((A[i]+sum)*x)%p;
//这里套用秦九韶算法求多项式的值
}
return !sum;//如果答案是0说明x值为该多项式的解,返回1(true)
}
int main(){
n=read();
m=read();
for(ll i=0;i<=n;i++){
A[i]=read();
}
for(ll i=1;i<=m;i++){
if(calc(i)){//如果返回的是1(true)则说明有解
t=false;
ans++;//记录答案个数
key[++cnt]=i;//记录每个解的值
}
}
if(t){
cout<<ans<<endl;//如果t未改变则说明解的个数为0
return 0;
}
print(ans);
printf("\n");
for(ll i=1;i<=cnt;i++){
print(key[i]);
printf("\n");
}
return 0;
}
そして、アルゴリズムの時間計算量はO(N * M)、Aへのこの質問のうち、このようについてです