ARC105 D.Let‘s Play Nim,E.Keep Graph Disconnected題解
ARC105 D.Let’s Play Nim,E.Keep Graph Disconnected題解
總結兩個非常好的博弈題!
D. Let’s Play Nim
相信大家都知道NIM遊戲的結論吧: 如果 ⊕ x i = 0 \oplus x_i=0 ⊕xi=0則後手必勝,否則先手必勝。
則問題轉變為:
輪流將一個包裡的東西放到盤子裡,問最後拿出包裡物品的人能否讓 ⊕ x i = 0 \oplus x_i=0 ⊕xi=0?
這個比較複雜,我們可以分情況討論。
-
若每一個物品出現的次數為偶數,則後手必勝。這是顯然的,由於後手可以不斷復刻先手的操作。
-
否則,我們考慮倒數第二個拿走的那個人,如果他在沒用的那兩個中選擇最大的,放入權值最大的盤子中,這個盤子裡的權值和最終一定 ≥ s u m 2 \geq \frac{sum}2 ≥2sum 。這說明了什麼呢?我們不妨可以再次分類討論:
-
若 max { w i } > s u m 2 \max\{w_i\}>\frac{sum}2 max{wi}>2sum,則其餘盤子異或和一定 < max { w i } <\max\{w_i\} <max{wi},則最終的異或和 ≠ 0 \neq 0 =0 (Tips:異或可以看作不進位的加法! )
-
若 max { w i } = s u m 2 \max\{w_i\}=\frac{sum}2 max{wi}=2sum ,假設其餘盤子裡的異或和 = s u m 2 =\frac{sum}2 =2sum,若這個滿足,最後放入的兩個數一定相等。這個歸納一下就會發現這正是case1。
綜上所述:若每一個數出現的次數都為偶數,後手必勝;否則拿走倒數第二個的人必勝。
-
總結:這題只需要分類討論,耐心證明就可以快速做出來。結論還是比較優美的!
Code:
/*
{
######################
# Author #
# Gary #
# 2020 #
######################
*/
//#pragma GCC target ("avx2")
//#pragma GCC optimization ("O3")
//#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
map<int,int> app;
int N;
void solve(){
app.clear();
scanf("%d",&N);
rb(i,1,N)
{
int ai;
scanf("%d",&ai);
app[ai]++;
}
bool ok=true;
for(auto ite=app.begin();ite!=app.end();ite++){
ok&=!((ite->SEC)&1);
}
ok^=1;
ok^=(N&1);
cout<<(ok? "First":"Second")<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
/** 程式框架:
*
*
*
*
**/
E. Keep Graph Disconnected
考驗思維的題目!(做了一晚上總算自己獨自ac了)
首先若只剩下兩個聯通快(1所在的和n所在的),最終誰會勝利呢?
很明顯,和能夠加的邊數有關。設1所在的聯通塊能加入的邊數為 c 1 c_1 c1,n所在的為 c 2 c_2 c2。
則可以發現若 c 1 + c 2 c_1+c_2 c1+c2為奇數,先手勝。否則後手勝。
我們擴充套件到一般情況,若有多個聯通快,總共能加的邊數為 K K K(假設不在聯通快之間連邊)。
若 K K K為奇數,顯然答案可能不是先手!這是為什麼呢?
後手可以在塊與塊之間連邊,打破原來的規律!
怎麼解決?
假設在聯通快 i i i與 j j j之間連一條邊,我們冷靜分析就會發現:
- 若 c i ≡ c j ≡ 1 ( m o d 2 ) c_i≡c_j≡1(\mod 2) ci≡cj≡1(mod2),則在i,j之間連一條邊之後會增加 c i ∗ c j c_i*c_j ci∗cj條邊 ≡ 1 ( m o d 2 ) ≡1(\mod 2) ≡1(mod2),最後在減去連線的這條邊,奇偶性相當於沒變,相當於反轉了勝負。
- 其他情況下奇偶性就會改變,和一個聯通快內的影響是一樣的。
這樣假設奇數塊有 Z Z Z個。
- 若 Z Z Z是奇數,反轉的次數為 ⌊ Z / 2 ⌋ \lfloor Z/2\rfloor ⌊Z/2⌋
- 若 Z Z Z是偶數,反轉的次數為 [ Z / 2 , Z / 2 − 1 ] [Z/2,Z/2-1] [Z/2,Z/2−1]次(若最後剛好剩下1號塊和n號塊都是奇數)
這個 [ Z / 2 , Z / 2 − 1 ] [Z/2,Z/2-1] [Z/2,Z/2−1]對於比賽的勝負至關重要。
最終問題轉變成:
先手/後手能否使得最後1號塊和2號塊都為奇數?
看似任然不好做。
其實這存在一個非常優美的結論:
- 若初始狀態1,2的奇偶性不一樣,則先手一定可以完成目標。
- 若1,2初始都為1,則不管先後手都可以完成目標
- 若1,2初始都為0,則不管先後手都不可能。
具體方法大概就是,若已經滿足要求就隨便拿兩個消掉,否則用一個實現目標。
Code:
/*
{
######################
# Author #
# Gary #
# 2020 #
######################
*/
//#pragma GCC target ("avx2")
//#pragma GCC optimization ("O3")
//#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=100000+20;
int n,m;
int fa[MAXN];
int cnt_node[MAXN],cnt_edge[MAXN],cnt[MAXN];
int root(int x){return fa[x]=(fa[x]==x? x:root(fa[x]));}
string result[2]={"First","Second"};
int cnt_1,cnt_0;
bool check(bool cnt_o,bool who){
if(cnt_node[root(1)]==cnt_node[root(n)]){
if(cnt_node[root(1)]==0){
return false;
}
else{
return true;
}
}
else{
return (!who);
}
}
void solve(){
scanf("%d %d",&n,&m);
rb(i,1,n)
cnt_node[i]=cnt_edge[i]=cnt[i]=0,fa[i]=i;
vector<mp> edges;
rb(i,1,m){
int u,v;
scanf("%d %d",&u,&v);
edges.PB(II(u,v));
fa[root(u)]=root(v);
}
for(auto it:edges)
cnt_edge[root(it.FIR)]++;
rb(i,1,n)
cnt_node[root(i)]^=1;
bool rest=0;
cnt_1=0,cnt_0=0;
rb(i,1,n){
cnt[root(i)]++;
if(cnt_node[i])
cnt_1+=cnt_node[i];
else
if(root(i)==i)
++cnt_0;
}
rb(i,1,n){
if(root(i)==i){
rest^=(1ll*cnt[i]*(cnt[i]-1)/2-cnt_edge[i])&1;
}
}
bool ok;
int times=(cnt_1)/2;
times&=1;
if(cnt_1&1){
if(times^rest){
ok=0;
}
else{
ok=1;
}
}
else{
if((times^rest)){
ok=check(cnt_0&1,1);
}
else{
ok=!check(cnt_0&1,0);
}
}
cout<<result[ok]<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
/** 程式框架:
*
*
*
*
**/
推薦閱讀:
相關文章
- CF466E Information Graph 題解ORM
- LeetCode每日一題:Nim遊戲(No.292)LeetCode每日一題遊戲
- csp-s真題題解
- POJ 2975 Nim
- 「KDOI-06-S」題解
- 論文解讀(Graph-MLP)《Graph-MLP: Node Classification without Message Passing in Graph》
- 論文解讀(AGE)《Adaptive Graph Encoder for Attributed Graph Embedding》APT
- qzezoj[Moocast-S]題解--zhengjunAST
- E. Not a Nim Problem
- [20230108]ORA-00600 and Session Disconnected.txtSession
- 論文解讀(GMT)《Accurate Learning of Graph Representations with Graph Multiset Pooling》
- 論文解讀(AGC)《Attributed Graph Clustering via Adaptive Graph Convolution》GCAPT
- 「KDOI-06-S」消除序列 題解
- 論文解讀GALA《Symmetric Graph Convolutional Autoencoder for Unsupervised Graph Representation Learning》
- Leetcode 292. Nim GameLeetCodeGAM
- [20230108]ORA-00600 and Session Disconnected 2.txtSession
- 論文解讀(LG2AR)《Learning Graph Augmentations to Learn Graph Representations》
- [CSP-S 2021] 廊橋分配 題解
- 論文解讀《Cauchy Graph Embedding》
- CSP-S/NOIP提高組 真題題解總結
- ERR_INTERNET_DISCONNECTED devtool 設定offline 忘了關。。。。dev
- NIM遊戲/SG函式遊戲函式
- 論文解讀(GCC)《GCC: Graph Contrastive Coding for Graph Neural Network Pre-Training》GCASTAI
- 論文解讀(GCC)《Graph Contrastive Clustering》GCAST
- 論文解讀(DGI)《DEEP GRAPH INFOMAX》
- Nim遊戲2(臺階型)遊戲
- 第六章 數學問題 -------- 6.2【Nim遊戲】高僧鬥法遊戲
- gym105167E Erdős-Ginzburg-Ziv 題解
- 洛谷 P3034 Cow Photography G/S——題解
- [題解]P9755 [CSP-S 2023] 種樹
- P11231 [CSP-S 2024] 決鬥 題解
- 論文解讀(gCooL)《Graph Communal Contrastive Learning》GCAST
- 論文解讀(SCGC)《Simple Contrastive Graph Clustering》GCAST
- 小米Play有人臉識別功能嗎?小米Play人臉解鎖的設定方法教程
- 論文解讀(SUBG-CON)《Sub-graph Contrast for Scalable Self-Supervised Graph Representation Learning》AST
- BZOJ4589: Hard Nim(FWT 快速冪)
- Google Play開發者賬號被封,相關問題彙總以及解決方案探索Go
- 上傳APP到Google Play許可權問題APPGo