题意:
一开始有一个多项式
P(x)=an∗xn+an−1∗xn−1+⋯+a1∗x+a0
系数未知,人和电脑轮流最优确定一个系数,问最后能不能使 P(x)=B(x)∗Q(x) 成立,成立人就赢了,否则电脑赢,电脑先走。
其中 Q(x)=x−k , k 是已知常数。
输入不一定会给出初始局面,也可能给出进行了几次之后的局面,所以给出的局面可能是该人走,也可能该电脑走,已知的系数是整数,未知的系数可以填任意实数。
题解:
由于要满足
J=an∗kn+an−1∗kn−1+⋯+a1∗k+a0
问题转变成让余数 J 为0。
所以要考虑两种情况:
当
当 k!=0 ,如果有系数没有确定, 因为 ai 可以取任意值,容易看出最后走的人必胜,如果全部系数都确定了,只需要判断 J=0 ,由于 n 可能会很大,只能考虑取余,如果
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
const ll mod = 1e9+7;
int a[N], n, k;
char s[10];
bool issur[N];
int get(char *s){
int flag = 1, res = 0;
if(s[0] == '-') flag = -1;
else res = s[0]-'0';
for(int i = 1; s[i]; ++i){
res = res*10+s[i]-'0';
}
return flag*res;
}
bool cal(ll mod){
ll res = 0;
for(int i = n; i >= 0; --i){
res = res*k%mod+a[i];
res %= mod;
}
return res;
}
int main(){
int flag = 0, sur = 0, hf = 0;
scanf("%d%d", &n, &k);
for(int i = 0; i <= n; ++i){
scanf("%s", s);
if(s[0] == '?') ++flag;
else a[i] = get(s), sur++, issur[i] = 1, hf = !hf;
}
if(k == 0){
if(!issur[0]) puts(hf? "Yes" : "No");
else puts(a[0]? "No" : "Yes");
return 0;
}
if(flag){
if(flag%2 != sur%2) puts("No");
else puts("Yes");
}
else{
for(int i = 0; i < 100; ++i){
if(cal((ll)rand()*11234ll*5135ll*15ll%mod)){ puts("No"); return 0; }
}
puts("Yes");
}
}