CF676E The Last Fight Between Human and AI(特判)(脑洞)

版权声明:转载请声明出处,谢谢支持 https://blog.csdn.net/Dreamstar_DS/article/details/82828852

题目链接:http://codeforces.com/contest/676/problem/e

题意:现在给你一组多项式,给出一个中间状态,此时有些系数可能是确定的,有些系数可能是不确定的(用?表示),机器人和人将轮流为未知数设值(由于是中间状态所以当前第一个设值的人不一定是机器人),给你整数k,求人类在不管机器人如何设值的情况下,是否能让最终的f(k) = 0。

这道题我们需要分情况讨论:
①k == 0
此时常数项必须为0,所以如果常数项已确定,那么如果其为0的话输出YES(已经不用管非常数项了),否则输出NO,如果未确定,那么如果下一步是人类操作的话输出YES,否则输出NO
②k != 0 && 所有值都已确定
相当于我们现在要判断一个多项式的值是否为0,由于次数可能会很大,所以我们采取%质数的方法判断是否为0(0 % ANY number = 0),但是本题出了几个很(du)妙(liu)的数据,针对一些小质数(可能是1000以内的),还有常用质数(1e9 + 7之类的)专门设计了一下,因此建议多模几个大质数,或者搞点随机数什么的也行,别忘了开longlong
③有不确定的值
如果有不确定的值,相当于最终操作的一方是在为一个一次函数的自变量取值,所以此时一定有解,因此我们只需要判断最终是谁进行最后一次操作即可

AC Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#define rg register
#define il inline
#define maxn 500005
#define ll long long
#define eps 1e-8
#define lid id << 1
#define rid (id << 1) | 1
#define out -10001
#define rep(a,b,c) for (rg int a = 1 ; a <= c ; a += b)
using namespace std;
int cnt  , a[maxn];
ll f[10][maxn]  , prime[4] = {7 , 19260817 , 1000000007 , 1000000009};
il int read(){rg int x = 0 , w = 1;rg char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-') w = -1;else if (ch == '?') {++cnt ; return out;}ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0';ch = getchar();}return x * w;}
int main(){
    rg int n = read() , k = read();
    for (rg int i = 0 ; i <= n ; ++i)
		a[i] = read();
	if (!k){
		if (!a[0]) {cout << "Yes";return 0;}
		else if (a[0] != out) {cout << "No";return 0;}
		else if ((n + 1 - cnt) & 1) {cout << "Yes";return 0;}
		else {cout << "No";return 0;}
	}
	if (!cnt){
		for (rg int i = 0 ; i < 4 ; ++i){
			f[i][0] = 1;
			rg ll kk = k % prime[i];
			for (rg int j = 1 ; j <= n ; ++j)
				f[i][j] = (f[i][j - 1] * kk) % prime[i];
		}
		ll res = 0;
		bool ok = 1;
		for (rg int i = 0 ; i < 4 ; ++i){
			ok = 1;
			res = a[0];
			for (rg int j = 1 ; j <= n ; ++j){
				res = (res + (ll)(a[j] % prime[i]) * f[i][j]) % prime[i];
			}
			if (res) {ok = 0;break;} 
		}
		if (!ok) {cout << "No";return 0;}
		else {cout << "Yes";return 0;}
	}else{
		rg int res = n + 1 - cnt;
		if (((res & 1) && (cnt & 1)) || (!(res & 1) && !(cnt & 1))) {cout << "Yes";return 0;}
		else {cout << "No";return 0;}
	}
    return 0;
}```

猜你喜欢

转载自blog.csdn.net/Dreamstar_DS/article/details/82828852