很美妙的一题
官方题解 http://www.cnblogs.com/duoxiao/p/5777632.html
感觉有meet in middle的思想
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int mo=1e9+7; 6 struct way{int po,next;} e[400010]; 7 unsigned int mx[260][260],f[70010],tmp[70010][260]; 8 int n,w[70010],fa[70010],p[70010],v[260],ans,len; 9 char s[10]; 10 void add(int x,int y) 11 { 12 e[++len].po=y; 13 e[len].next=p[x]; 14 p[x]=len; 15 } 16 17 void inc(int &a,int b) 18 { 19 a+=b; 20 if (a>mo) a-=mo; 21 } 22 23 int calc(int a,int b) 24 { 25 if (s[0]=='X') return a^b; 26 else return a&b; 27 } 28 29 void get(int x) 30 { 31 if (x==1) f[x]=0; 32 else f[x]=f[fa[x]]+(w[x]|w[fa[x]]); 33 inc(ans,(ll)x*(f[x]+w[x])%mo); 34 for (int i=p[x]; i; i=e[i].next) get(e[i].po); 35 } 36 37 void dfs(int x) 38 { 39 f[x]=0; 40 int a=w[x]>>8,b=w[x]&255; 41 for (int i=0; i<256; i++) 42 if (v[i]) f[x]=max(f[x],mx[i][b]+(calc(a,i)<<8)); 43 inc(ans,(ll)x*(f[x]+w[x])%mo); 44 v[a]++; 45 for (int i=0; i<256; i++) 46 { 47 tmp[x][i]=mx[a][i]; 48 mx[a][i]=max(mx[a][i],f[x]+calc(b,i)); 49 } 50 for (int i=p[x]; i; i=e[i].next) dfs(e[i].po); 51 memcpy(mx[a],tmp[x],sizeof(tmp[x])); 52 v[a]--; 53 } 54 55 int main() 56 { 57 int cas; 58 scanf("%d",&cas); 59 memset(mx,0,sizeof(mx)); 60 while (cas--) 61 { 62 len=0; memset(p,0,sizeof(p)); 63 scanf("%d%s",&n,s); 64 for (int i=1; i<=n; i++) scanf("%d",&w[i]); 65 for (int i=2; i<=n; i++) 66 { 67 scanf("%d",&fa[i]); 68 add(fa[i],i); 69 } 70 ans=0; 71 memset(v,0,sizeof(v)); 72 if (s[0]=='O') get(1); 73 else dfs(1); 74 for (int i=1; i<=n; i++) p[i]=0; 75 printf("%d ",ans); 76 } 77 }