zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    二维差分与二维前缀和
    luogu P1854 花店橱窗设置
    HDU Multi-University Training Contest 4 HDU 6621 K-th Closest Distance
    POJ 3111-K Best (01分数规划)
    POJ 2976-Dropping tests(01分数规划入门)
    POJ 2796 Feel Good(单调栈)
    树状数组求逆序对
    树状数组学习笔记(线性初始化)
    UVALive 3905 Meteor (扫描线)
    Codeferce 1138B
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8928042.html
Copyright © 2011-2022 走看看