[數學] codeforces 676E. The Last Fight Between Human and AI

題意:
一開始有一個多項式

P(x)=anxn+an1xn1++a1x+a0

係數未知,人和電腦輪流最優確定一個係數,問最後能不能使P(x)=B(x)Q(x) 成立,成立人就贏了,否則電腦贏,電腦先走。
其中Q(x)=xkk 是已知常數。
輸入不一定會給出初始局面,也可能給出進行了幾次之後的局面,所以給出的局面可能是該人走,也可能該電腦走,已知的係數是整數,未知的係數可以填任意實數。
題解:
由於要滿足P(x)=B(x)Q(x) ,先手算一下任意情況下的多項式除法,用P(x) 除以Q(x) ,算出餘數大概長這樣:
J=ankn+an1kn1++a1k+a0

問題轉變成讓餘數J 爲0。
所以要考慮兩種情況:
k=0 ,那麼必須要讓a0=0 ,根據a0 是否已知,當前該誰先走,討論一下就行了。
k!=0 ,如果有係數沒有確定, 因爲ai 可以取任意值,容易看出最後走的人必勝,如果全部係數都確定了,只需要判斷J=0 ,由於n 可能會很大,只能考慮取餘,如果J=0 ,那麼對任意數取餘都還是0 ,因此隨機一系列數進行檢驗就行了,要注意的是隻選1e9+7和1e9+9的話是不行的,有針對數據。
#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");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章