SPOJ:Ada and Graft (set合并&优化)

As you might already know, Ada the Ladybug is a farmer. She grows a big fruit tree (with root in 0). There is a fruit on every node of the tree. Ada is competing in grafting competition and this is her masterpiece. The most valuable tree wins the competition. The value of tree is product of values of each node. The value of a node is the number of distinct fruit kinds in its subtree.

Can you find the value of Ada's tree? Since this number might be pretty big, output it modulo 109+7

Input

The first and line will contain 1 ≤ N ≤ 4*105.

The next line will contain N-1 integers 0 ≤ pi < i, the parent of ith node.

The next line will contain N integers 0 ≤ Fi ≤ 109, the fruit growing on ith node.

Output

Print a single integer - the value of tree modulo 1000000007.

Example Input

5
0 0 1 1
1 1 1 2 2

Example Output

4

Example Input

4
0 1 2
6 7 2 3

Example Output

24

Example Input

11
0 1 1 1 3 5 2 7 5 4
494052753 959648710 959648710 959648710 494052753 959648710 959648710 959648710 959648710 494052753 959648710

Example Output

32

题意:给定一棵树,每个节点有自己的颜色,现在求每个节点的子树的颜色种类之积,结果模1e9+7;

思路:用set合并,合并的时候可以用小的集合加到大集合里,得到每个节点的子树有哪些颜色,swap之前保证记录答案就行。(bitset我试过,会超时)。

#include<set>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int Mod=1e9+7;
const int maxn=400010;
set<int>s[maxn];
int a[maxn],id[maxn],f[maxn];
int Laxt[maxn],Next[maxn],To[maxn],cnt;
void read(int &x){
    x=0;char c=getchar();
    while(c>'9'||c<'0') c=getchar();
    while(c>='0'&&c<='9'){
        x=(x<<3)+(x<<1)+c-'0'; c=getchar();
    }
}
void add(int u,int v){
    Next[++cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
}
void merge(int &u,int &v){
    if(s[u].size()>s[v].size()) swap(u,v);
    set<int>:: iterator it ;
    for(it=s[u].begin();it!=s[u].end();it++)
      s[v].insert(*it);
}
void dfs(int u,int fa){
    for(int i=Laxt[u];i;i=Next[i]){
        dfs(To[i],u);
        merge(id[To[i]],id[u]);
    }
    f[u]=s[id[u]].size();
}
int main()
{
    int N,ans=1,x,i;
    scanf("%d",&N);
    for(i=1;i<N;i++){
        read(x); add(x,i);
    }
    for(i=0;i<N;i++){
        id[i]=i; read(x);
        s[i].insert(x);
    }
    dfs(0,-1);
    for(i=0;i<N;i++) ans=((ll)ans*f[i]%Mod)%Mod;
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/8928042.html