【题解】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. .net core项目启动时报_未处理Socket异常(以一种访问权限不允许的方式做了一个访问套接字的尝试。)

    解决方案:一般的原因就是程序的端口被占用了,关掉占用端口的程序即可正常使用.  查看启动地址和配置的webserver服务器的端口号是否被占用,可能占用的有:IIS启用项目,解决方案中其他启动项目配置 ...

  2. 这些好用却鲜为人知的Python库,你知道多少?

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 读芯术 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  3. Ajax的快速入门

    1.什么是ajax ajax是技术名词的缩写: Asynchronous:异步: JavaScript:JavaScript语言: And:和.与: XML:数据传输格式 ajax是客户端通过HTTP ...

  4. 利用windbg分析崩溃,句柄泄漏,死锁,CPU高,内存泄漏

    Windbg的一些简单使用命令 一.崩溃 1.  输入.ecxr;kbn得到崩溃的堆栈 其中源代码如下 2.  查看堆栈和源代码,发现第0帧导致崩溃,代码也是本地代码 输入.frame  0,切到第0 ...

  5. 前端开发JS——jQuery常用方法

    jQuery基础(三)- 事件篇   1.jQuery鼠标事件之click与dbclick事件 click方法用于监听用户单击操作,dbclick方法用于监听用户双击操作,这两个方法用法及其类似,所以 ...

  6. App iCON 尺寸

    120*120  180*180 58*58  87*87 80*80  120*120

  7. Linux使用Samba实现文件共享

    Samba服务是现在Linux系统与Windows系统之间共享文件的最佳选择. [root@study ~]# yum install samba -y #安装samba服务 [root@study ...

  8. python3.5.3rc1学习四:类

    class calculator: def add(x,y): return x + y print(added) def sub(x,y): return x - y print(sub) def ...

  9. python 连接oracle -- sqlalchemy及cx_Oracle的使用详解

    python连接oracle -- sqlalchemy import cx_Oracle as orcl import pandas as pd from sqlalchemy import cre ...

  10. hdu 6495 dp

    http://acm.hdu.edu.cn/showproblem.php?pid=6495 题意 有n个挑战(1e3),假如接受,在挑战之前体力x会变成min(x,\(b[i]\)),然后会减去a[ ...