標籤:tree pac ace == microsoft lag void log int
之前在bc上做過一道類似的階梯博弈的題目,那題是移動到根,這題是移動到葉子。換湯不換藥,只要和終態不同奇偶的那些位置做nim即可。因此這題給出了一個條件:所有葉子深度的奇偶性相同。同時需要注意的是,上次bc中,根節點是不能移動的,因此根節點是終態節點,而這裡葉子上面還可以進行操作(可以吃掉),那麼就相當於葉子節點都還可以繼續向下移動,因此他們不是終態節點,也就是說這題只要和葉子節點同奇偶的做nim即可。
因此,如果nim和已經是0,已經可以滿足先手必輸了,而題目說了必須要交換,那麼只要讓奇偶性相同的節點做交換即可,統計一下奇偶節點的個數再C(cnt, 2)就做完了;否則,後手必須要把和葉子節點不同奇偶的換過去來使得nim和為0,利用異或的性質以及map就可以做出來了。具體見代碼:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <map> 5 #include <vector> 6 #include <iostream> 7 using namespace std; 8 const int N = 1e5 + 5; 9 typedef long long ll;10 11 int a[N];12 vector<int> G[N];13 int n;14 int ji = -1;15 void dfs(int u,int fa,int deep)16 {17 if(ji != -1) return ;18 int flag = 0;19 for(int i=0;i<G[u].size();i++)20 {21 int v = G[u][i];22 if(v != fa)23 {24 flag = 1;25 dfs(v, u, deep + 1);26 }27 }28 if(flag == 0)29 {30 ji = deep % 2;31 }32 }33 vector<int> yes, no;34 void dfs2(int u,int fa,int deep)35 {36 if(deep % 2 == ji) yes.push_back(a[u]);37 else no.push_back(a[u]);38 for(int i=0;i<G[u].size();i++)39 {40 int v = G[u][i];41 if(v != fa)42 {43 dfs2(v, u, deep + 1);44 }45 }46 }47 ll comb(int x) {if(x < 2) return 0; return (ll)x*(x-1) / 2;}48 49 int main()50 {51 scanf("%d",&n);52 for(int i=1;i<=n;i++) scanf("%d",a+i);53 for(int i=2;i<=n;i++)54 {55 int v;56 scanf("%d",&v);57 G[i].push_back(v);58 G[v].push_back(i);59 }60 dfs(1, -1, 1);61 dfs2(1, -1, 1);62 int temp = 0;63 for(int i=0;i<yes.size();i++) temp ^= yes[i];64 if(temp == 0)65 {66 ll ans = comb(yes.size()) + comb(no.size());67 map<int,int> inyes;68 for(int i=0;i<yes.size();i++) inyes[yes[i]]++;69 for(int i=0;i<no.size();i++) ans += (ll)inyes[no[i]];70 cout << ans << endl;71 }72 else73 {74 ll ans = 0;75 map<int,int> inno;76 for(int i=0;i<no.size();i++) inno[no[i]]++;77 for(int i=0;i<yes.size();i++)78 {79 ll t2 = temp ^ (yes[i]);80 ans += inno[t2];81 }82 cout << ans << endl;83 }84 return 0;85 }
Codeforces 812E Sagheer and Apple Tree ——(階梯博弈)