【题解】ADAGRAFT - Ada and Graft [SP33331]

传送门:\(\text{Ada and Graft}\) \(\text{[SP33331]}\)

【题目描述】

给出一颗 \(n\) 个节点的树(根为 \(0\)),树的价值定义为每个节点的价值乘积。每个节点的值是其子树中不同颜色种类的数量。

给出每个节点上的颜色,求树价值。答案对 \(10^9+7\) 取模。

【输入】

第一行包含一个整数 \(n\)。

第二行包含 \(n-1\) 个整数 \(p_{i}\),分别表示节点 \(i\) 的父亲节点。

第三行包含 \(n\) 个整数 \(F_{i}\),表示节点 \(i\) 的颜色。

【输出】

输出一个整数表示答案模 \(10^9+7\) 的值。

【样例】

样例输入1:
5
0 0 1 1
1 1 1 2 2 样例输出1:
4 样例输入2:
4
0 1 2
6 7 2 3 样例输出2:
24 样例输入3
11
0 1 1 1 3 5 2 7 5 4
494052753 959648710 959648710 959648710 494052753 959648710 959648710 959648710 959648710 494052753 959648710 样例输出3
32

【数据范围】

\(100\%\) \(1 \leqslant N \leqslant 4*10^5,\) \(1 \leqslant F_{i} \leqslant 10^9,\) \(0 \leqslant p_{i} \leqslant i\)


【分析】

求以某个节点为根的子树信息,很明显的线段树合并。

考虑将所有点的权值离散化一下,对每个节点开一颗动态开点权值线段树,按照 \(dfs\) 的遍历顺序不断合并所有子节点,便可得到所有节点的价值,最后乘起来即可。

合并两个权值线段树时可以直接取 \(or\),向上传递信息直接 \(S[p]=S[pl]+S[pr]\)。

注意取模!!!

【Code】

#include<algorithm>
#include<cstdio>
#define LL long long
#define Re register int
using namespace std;
const int N=4e5+3,P=1e9+7;
int n,m,x,y,o,Ans=1,A[N],B[N],pt[N],ans[N],head[N];
struct QAQ{int to,next;}a[N<<1];
inline void add(Re x,Re y){a[++o].to=y,a[o].next=head[x],head[x]=o;}
inline void in(Re &x){
Re fu=0;x=0;char ch=getchar();
while(ch<'0'||ch>'9')fu|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=fu?-x:x;
}
struct Segment_Tree{
#define pl tr[p].lp
#define pr tr[p].rp
#define mid (L+R>>1)
int cnt;
struct QAQ{int S,lp,rp;}tr[N*38];//空间要开够
inline void pushup(Re p){tr[p].S=tr[pl].S+tr[pr].S;}
inline void change(Re &p,Re L,Re R,Re w){
if(!p)p=++cnt;
if(L==R){tr[p].S=1;return;}
if(w<=mid)change(pl,L,mid,w);
else change(pr,mid+1,R,w);
pushup(p);
}
inline int merge(Re p,Re q,Re L,Re R){
if(!p)return q;if(!q)return p;
if(L==R){tr[p].S|=tr[q].S;return p;}//合并信息
pl=merge(pl,tr[q].lp,L,mid);
pr=merge(pr,tr[q].rp,mid+1,R);
pushup(p);return p;
}
}T1;
inline void dfs(Re x,Re fa){
for(Re i=head[x],to;i;i=a[i].next)
if((to=a[i].to)!=fa)
dfs(to,x),pt[x]=T1.merge(pt[x],pt[to],1,m);
ans[x]=T1.tr[pt[x]].S;//直接获取整个大区间的答案
}
int main(){
// freopen("123.txt","r",stdin);
in(n);
for(Re i=2;i<=n;++i)in(x),add(++x,i),add(i,x);
for(Re i=1;i<=n;++i)in(A[i]),B[i]=A[i];
sort(B+1,B+n+1),m=unique(B+1,B+n+1)-B-1;
for(Re i=1;i<=n;++i)T1.change(pt[i],1,m,lower_bound(B+1,B+m+1,A[i])-B);//初始化建树
dfs(1,0);
for(Re i=1;i<=n;++i)Ans=(LL)Ans*ans[i]%P;
printf("%d\n",Ans);
}

【题解】ADAGRAFT - Ada and Graft [SP33331]的更多相关文章

  1. 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). ...

  2. SPOJ ADAFIELD Ada and Field(STL的使用:set,multiset,map的迭代器)题解

    题意:n*m的方格,“0 x”表示x轴在x位置切一刀,“0 y”表示y轴在y位置切一刀,每次操作后输出当前面积最大矩形. 思路:用set分别储存x轴y轴分割的点,用multiset(可重复)储存x轴y ...

  3. Ada and Coins

    Ada and Coins 题意:钱包里有n种钱,然后有m次询问,询问[l,r]区间内能被表示的个数有几个. 题解:这道题是群主推荐我写的,然后让我用bitset去写,他说 操作32个bitset需要 ...

  4. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  5. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  6. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  7. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  8. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  9. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

随机推荐

  1. java高并发系列 - 第2天:并发级别

    由于临界区的存在,多线程之间的并发必须受到控制.根据控制并发的策略,我们可以把并发的级别分为阻塞.无饥饿.无障碍.无锁.无等待几种. 阻塞 一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继 ...

  2. wpf 单例模式和异常处理 (原发布 csdn 2017-04-12 20:34:12)

    第一次写博客,如有错误,请大家及时告知,本人立即改之. 如果您有好的想法或者建议,我随时与我联系. 如果发现代码有误导时,请与我联系,我立即改之. 好了不多说,直接贴代码. 一般的错误,使用下面三个就 ...

  3. WPF线段式布局的一种实现

    线段式布局 有时候需要实现下面类型的布局方案,不知道有没有约定俗成的称呼,我个人强名为线段式布局.因为元素恰好放置在线段的端点上. 实现 WPF所有布局控件都直接或间接的继承自System.Windo ...

  4. VS中怎样对C#项目进行单元测试

    场景 SpringBoot+Junit在IDEA中实现查询数据库的单元测试: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/927 ...

  5. Windows下 gcc/g++的安装与配置

    引言 我们知道开发最好用Mac/Linux,效率很高,但是对于很多还是Windows用户的我们来说,编写代码再到linux上运行也是很常有的事情,但对于我们写一些小demo使用上面的流程难免有点兴师动 ...

  6. 仅用StoryBoard布局实现按钮的均匀分布

    今天在做登录界面时设计的需求是,登录和取消按钮左右对称均匀分布,按钮大小不变如图 屏幕宽度变化时按钮宽度不变,三个间距相等并且随屏幕变化而变化,简单的说就是按钮均匀分布,在网上查了一些资料,弄得比较乱 ...

  7. 详细设计文档(final)

    1. 引言 1.1编写目的 本部分旨在阐明编写详细设计的目的,面向读者对象. 本文档主要描述各个模块的细节设计,明确软件的结构与实现过程,分析各个模块,描述模块的功能.性能和结构等方面包括模块接口.调 ...

  8. xposed 原理分析

    1.添加hook方法 首先是init进程打开 app_process,然后进入XposedInit.java main() - > initForZygote() 加入对ActivityThre ...

  9. 改名移动批量文件 shutil.copy

    import glob import os import shutil filePath = 'F:/project/Breast/InBreast/INBreast/imgout/' newFile ...

  10. 4.web基础$_POST