1. 程式人生 > >(博弈sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

(博弈sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

paths 相同 friend pri 產生 chan star ren have

Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered from 1 to n and rooted at node 1. The i-th node has ai apples. This tree has a special property: the lengths of all paths from the root to any leaf have the same parity (i.e. all paths have even length or all paths have odd length).

Sagheer and Soliman will take turns to play. Soliman will make the first move. The player who can‘t make a move loses.

In each move, the current player will pick a single node, take a non-empty subset of apples from it and do one of the following two things:

  1. eat the apples, if the node is a leaf.
  2. move the apples to one of the children, if the node is non-leaf.

Before Soliman comes to start playing, Sagheer will make exactly one change to the tree. He will pick two different nodes u and v and swap the apples of u with the apples of v.

Can you help Sagheer count the number of ways to make the swap (i.e. to choose u and v) after which he will win the game if both players play optimally? (u

,?v) and (v,?u) are considered to be the same pair.

Input

The first line will contain one integer n (2?≤?n?≤?105) — the number of nodes in the apple tree.

The second line will contain n integers a1,?a2,?...,?an (1?≤?ai?≤?107) — the number of apples on each node of the tree.

The third line will contain n?-?1 integers p2,?p3,?...,?pn (1?≤?pi?≤?n) — the parent of each node of the tree. Node i has parent pi (for 2?≤?i?≤?n). Node 1 is the root of the tree.

It is guaranteed that the input describes a valid tree, and the lengths of all paths from the root to any leaf will have the same parity.

Output

On a single line, print the number of different pairs of nodes (u,?v), u?≠?v such that if they start playing after swapping the apples of both nodes, Sagheer will win the game. (u,?v) and (v,?u) are considered to be the same pair.

Example

Input
3
2 2 3
1 1
Output
1
Input
3
1 2 3
1 1
Output
0
Input
8
7 2 2 5 4 3 1 1
1 1 1 4 4 5 6
Output
4

Note

In the first sample, Sagheer can only win if he swapped node 1 with node 3. In this case, both leaves will have 2 apples. If Soliman makes a move in a leaf node, Sagheer can make the same move in the other leaf. If Soliman moved some apples from a root to a leaf, Sagheer will eat those moved apples. Eventually, Soliman will not find a move.

In the second sample, There is no swap that will make Sagheer win the game.

Note that Sagheer must make the swap even if he can win with the initial tree.

題意:

一棵樹,滿足每個葉子結點的深度奇偶性相同,每個結點上放有一定數量物品,每次操作可以選擇某一結點的一些物品(數量不為0),如果是葉子結點,去掉這些物品,非葉子結點,將這些物品下放到某一子結點。現後手可以先交換某兩個結點的物品,求解有多少種交換方法使得後手可以取得勝利。(u、v和v、u算同一種交換)

解題思路:

容易發現這是nim遊戲的一個變形。對於nim遊戲,將所有堆的元素個數異或起來,如果得到0,則先手負,不然先手勝。

先考慮一個nim的簡單變形,如果遊戲中允許將某一堆加上若幹個(非0)物品(通過某種方式使這種操作有限),判斷勝負的方法與前同。因為這樣的操作如果由後手進行,先手可以直接去掉這些物品。

對於本題,可以轉換為上述nim的簡單變形。

首先,將所有葉子結點染為藍色,從葉子結點出發按紅-藍-紅……的順序不斷染其父結點。由於該樹滿足"每個葉子結點的深度奇偶性相同",所以通過這種染色方法,每個結點顏色是唯一的。將藍色結點視為nim變形中進行操作的物品堆,紅色結點視為上述nim變形中控制添加物品這一操作有限的方法。(因為紅色結點都不是葉子結點,進行操作後產生的影響是:其某一藍色子結點物品個數增加,即上述nim變形遊戲中的“添加”操作)

所以我們只需要考慮藍色結點的異或和。

先只考慮交換兩藍色結點、或兩紅色結點。

如果初始時異或和為0,則先手已經必負。任意交換兩藍色結點、或交換兩藍色結點均可。

如過初始時異或和非0,先手必勝,只交換藍色或紅色,並不會改變異或和。

再考慮交換藍色、紅色的情況。設原本藍色結點異或和為sum,想要交換的紅色結點為x,則只需要在藍色結點中找值為sum^x的結點個數(因為 sum^x^y=0 當且僅當y=sum^x)這可以通過之前用map記錄一下實現。

將上述方法個數求和即得到了可行的交換個數。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <queue>
 8 #include <set>
 9 #include <map>
10 #include <list>
11 #include <vector>
12 #include <stack>
13 #define mp make_pair
14 //#define P make_pair
15 #define MIN(a,b) (a>b?b:a)
16 //#define MAX(a,b) (a>b?a:b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 const int MAX=1e5+5;
20 const int MAX_V=1e3+5;
21 const ll INF=4e18+5;
22 const double M=4e18;
23 using namespace std;
24 const int MOD=1e9+7;
25 typedef pair<ll,int> pii;
26 const double eps=0.000000001;
27 #define rank rankk
28 int n,dep,parity,sum;
29 int a[MAX],d[MAX],cnt[3];
30 map <int,int> re;
31 ll an;
32 vector <int>edge[MAX];
33 void dfs(int rt)
34 {
35     for(int i=0;i<edge[rt].size();i++)
36     {
37         int to=edge[rt][i];
38         d[to]=d[rt]+1;
39         dep=max(dep,d[to]);
40         dfs(to);
41     }
42 }
43 int main()
44 {
45     scanf("%d",&n);
46     for(int i=1;i<=n;i++)
47         scanf("%d",&a[i]);
48     for(int i=2;i<=n;i++)
49     {
50         int rt;scanf("%d",&rt);edge[rt].push_back(i);
51     }
52     dfs(1);
53     parity=dep%2;
54     for(int i=1;i<=n;i++)
55     {
56         ++cnt[d[i]&1];d[i]=d[i]&1;
57         if(d[i]==parity)
58             sum^=a[i];
59     }
60     if(sum==0)
61     {
62          an+=(ll)cnt[1]*(cnt[1]-1)/2;
63          an+=(ll)cnt[0]*(cnt[0]-1)/2;
64     }
65     for(int i=1;i<=n;i++)
66         if(d[i]==parity)
67             ++re[a[i]];
68     for(int i=1;i<=n;i++)
69         if(d[i]!=parity)
70             an+=re[sum^a[i]];
71     printf("%I64d\n",an);
72 }

(博弈\sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree