[***]HZOI20190714 T2熟练剖分
这题真的神仙,蒟弱表示看题解看不懂……std看了几个小时大概看懂,还有一些细节的东西没有思考。
最难受的是题解和std好像并不是同一个人写的……数组状态不一样……看了好久才看出来f也是前缀和。
F[i][j]表示在点 i 为根的子树中,向下最长轻链长度小于等于 j 的概率。
首先递归下去并求出子树大小,然后枚举重儿子,枚举该点最长轻链长度,再次枚举儿子节点并逐个考虑(感觉和概率充电器(特地从考试总结中搬出来了)那个题有点类似),
假设当前枚举的重儿子是v(i),枚举到儿子节点v(j),x最长轻链长度为k,设gs为v(j)之前考虑的儿子中最长轻链长度为k的概率(因为是前缀和,所以代码中有减这个操作,f同理),如果v(j)=v(i)即v(j)为重儿子,则设fs为以v(j)为根的子树最长轻链长度为k的概率,f[x][k]=gs*f[v(j)][k](v(j)之前考虑的儿子为长度k*以v(j)为根字数长度<=k(此条边为重链所以可以等于))+fs*g[k]-gs*fs(去重),
如果v(j)是轻儿子,则设fs为以v(j)为根的子树最长轻链长度为k-1的概率,f[x][k]=gs*f[v(j)][k-1]+fs*g[k]-gs*fs,大致同上,只是x与v(j)相连的这条边为轻链所以有减1,值得提醒的一点是这里的f[x][k]并不是最终的f[x][k],只是考虑到当前几个儿子时的值,一个儿子一个儿子地向里加。考虑到f数组直接改的话会错,所以用h数组保存,最后加到g数组中清空h,当v(i)为重儿子这个情况考虑玩后将g数组加到f中去,清空g。当前节点x求完后,此时的f数组并不是前缀和,所以需要再次转化。
最后求答案时再次将前缀和转化为单个的值(换来换去好乱啊……)。
还有一点,时间复杂度不容乐观啊,转移的时候如果k循环到了 size[x],那么复杂度可以被卡到 N^3,我们发现当 k>size[v(j)]+1 的时候f[i]没有变,所以只要 k 循环到 size[v(j)]+1 就行了。
每个节点只有在 dp 它父亲时会被枚举成为重儿子,然后最多把整棵树的大小扫一遍,所以复杂度为$n^2$(蒟弱表示并不会证).
ps.有同学问我g数组的含义(好像是没写太清楚),g[k]=∑f[x][l](l<=k)即前缀和,可能用文字描述更好理解点,就是v(j)之前的儿子中最长轻链长度小于等于k的概率。
LL f[][],g[],h[],size[];
void dfs(int x)
{
size[x]=;
for(int i=f(x);i;i=n(i))dfs(v(i)),size[x]+=size[v(i)];
LL q=poww(du[x],mod-);
for(int i=f(x);i;i=n(i))//枚举重儿子
{
for(int j=;j<=n;j++)g[j]=;
for(int j=f(x);j;j=n(j))
{
for(int k=;k<=size[v(j)]+;k++)
{
LL gs=g[k]; if(k)gs-=g[k-];
LL fs=f[v(j)][k];if(k)fs-=f[v(j)][k-];
if(v(j)==v(i))h[k]= ((gs*f[v(j)][k]%mod+fs*g[k]%mod-gs*fs)%mod+mod)%mod;
else if(k)
{
fs=f[v(j)][k-];if(k>)fs-=f[v(j)][k-];
h[k]=( (gs*f[v(j)][k-]%mod+fs*g[k]%mod-fs*gs%mod)%mod+mod )%mod;
}
}
g[]=h[],h[]=;
for(int k=;k<=size[v(j)]+;k++)g[k]=(g[k-]+h[k])%mod,h[k]=;
}
for(int j=size[x];j;j--)g[j]=(g[j]-g[j-]+mod)%mod;
for(int j=;j<=size[x];j++)f[x][j]=(f[x][j]+g[j]*q%mod)%mod;
}
if(!f(x))f[x][]=;
for(int i=;i<=n;i++)f[x][i]=(f[x][i-]+f[x][i])%mod;
}
#include<iostream>
#include<cstdio>
#include<cmath>
#define LL long long
#define int LL
#define MAXN 50100
#define esp 1e-8
#define mod 1000000007
using namespace std;
struct edge
{
int u,v,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define n(x) ed[x].nxt
}ed[5000000];
int first[MAXN],num_e;
#define f(x) first[x]
int n,root;
int du[MAXN],ru[MAXN]; LL poww(LL a,int b);
inline void add(int u,int v)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
n(num_e)=f(u);
f(u)=num_e;
}
inline int read()
{
int s=0;char a=getchar();
while(a<'0'||a>'9')a=getchar();
while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
return s;
}
LL f[3010][3010],g[3010],h[3010],size[3010]; void dfs(int x)
{
size[x]=1;
for(int i=f(x);i;i=n(i))dfs(v(i)),size[x]+=size[v(i)];
// cout<<x<<" "<<size[x]<<endl; LL q=poww(du[x],mod-2);
for(int i=f(x);i;i=n(i))//枚举重儿子
{
for(int j=0;j<=n;j++)g[j]=1;
for(int j=f(x);j;j=n(j))
{
for(int k=0;k<=size[v(j)]+1;k++)
{
LL gs=g[k]; if(k)gs-=g[k-1];
LL fs=f[v(j)][k];if(k)fs-=f[v(j)][k-1];
if(v(j)==v(i))h[k]= ((gs*f[v(j)][k]%mod+fs*g[k]%mod-gs*fs)%mod+mod)%mod;
else if(k)
{
fs=f[v(j)][k-1];if(k>1)fs-=f[v(j)][k-2];
h[k]=( (gs*f[v(j)][k-1]%mod+fs*g[k]%mod-fs*gs%mod)%mod+mod )%mod;
}
}
g[0]=h[0],h[0]=0;
for(int k=1;k<=size[v(j)]+1;k++)g[k]=(g[k-1]+h[k])%mod,h[k]=0;
}
for(int j=size[x];j;j--)g[j]=(g[j]-g[j-1]+mod)%mod;
for(int j=0;j<=size[x];j++)f[x][j]=(f[x][j]+g[j]*q%mod)%mod;
}
if(!f(x))f[x][0]=1;
for(int i=1;i<=n;i++)f[x][i]=(f[x][i-1]+f[x][i])%mod;
}
signed main()
{
// freopen("in.txt","r",stdin); n=read();int a;
// for(int i=0;i<=n;i++)m[i]=1;
for(int i=1;i<=n;i++)
{
du[i]=read();
for(int j=1;j<=du[i];j++)
a=read(),add(i,a),ru[a]++;
}
bool pdl=1;
for(int i=1;i<=n;i++)
{
if(du[i]!=1&&du[i]!=0)pdl=0;
if(!ru[i])root=i;
}
dfs(root);
LL ans=0;
for(int i=1;i<=n;i++)ans=(ans+i*(f[root][i]-f[root][i-1]+mod)%mod)%mod;
printf("%lld\n",ans);
}
LL poww(LL a,int b)
{
LL ans=1;
while(b)
{
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b=b>>1;
}
return ans;
}
[***]HZOI20190714 T2熟练剖分的更多相关文章
- 20210501 序列,熟练剖分(tree),建造游乐园(play)
考场 \(65+5+0\),并列 rk2 最高分 \(55+10+10\) T1:等比数列可以写作 \(q^kx\),发现 \(q\le1000\) 且有一档分为 \(a_i\le100\),想到 \ ...
- 熟练剖分(tree) 树形DP
熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...
- NOIP模拟测试3「序列·熟练剖分·建造游乐园(play)」
---恢复内容开始--- 序列 刚调出来样例就A了,假装是水题. 因为是乱序,我们要求出来每两项之间最小公比,而不是直接比 求出来每两项之间最小公比,然后扫一遍就完了.(还要注意重复情况) 那么问题就 ...
- BZOJ 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...
- BZOJ 3672 [Noi2014]购票 (熟练剖分+凸壳维护)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3672 题意:给出一棵有根树(1为根),边有长度.每个点u有三个属性(len[u], ...
- HZOI2019熟练剖分(tree)
题目大意:https://www.cnblogs.com/Juve/articles/11186805.html 题解: 先给出官方题解: 其实这题跟期望没什么关系,因为E=$\sum_\limits ...
- 【模拟7.14】B. 熟练剖分(tree) (概率DP)
一道概率神题,考试时没读清题考完看了学长的玄学题解看了好几个小时 首先f[i][j]表示在点 i 为根的子树中,向下最长轻链长度小于等于 j 的概率. 首先递归下去并求出子树大小,然后枚举重儿子,枚举 ...
- Luogu2420 让我们异或吧 (熟练剖分)
\(dis[u] \bigoplus dis[v] = dis[u] \bigoplus dis[v] \bigoplus dis[lca\{x,y\}] \bigoplus dis[lca\{x,y ...
- 2021.5.22 noip模拟1
这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...
随机推荐
- 学习Python笔记---操作列表
1.for循环: 编写for循环时,对于用语存储列表中每个值的临时变量,可指定任何名称. 在for循环中,想包含多少行代码都可以,每个缩进的代码行都是循环的一部分,且将针对列表中的每个值都执行一次. ...
- Linux巨好用的
受不了了windows下配置烦死人.linux一站式搞定,无敌 安装python3 机子上py2 py3共存没问题 安装virtualenv (py3)分割实验环境非常稳 安装mysql 先安装了一 ...
- TYVJ4239 [NOIP2015提高组DayT3]斗地主
P2668 斗地主 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中, 牌的大小关系根据牌的数码表示如 ...
- 洛谷P1966 [NOIP2013提高组Day1T2]火柴排队
P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi) ...
- Eclipse 的 Java Web 项目环境搭建
从svn上拉取下来Eclipse的项目 IntelliJ IDEA自动识别到可编译的 src 类目录 Java Web 项目 html(一般命名为:WebRoot) 是整个项目输出的根目录. WEB- ...
- vue里调用moment.js
1.首先安装moment npm install moment --save 2.在main.js里引入 import moment from 'moment'//导入文件 Vue.prot ...
- web前端学习(二)html学习笔记部分(1) -- html5新增的元素及特性等等
检查,在浏览器中可以调整设备类型 html5实现水池效果. lang:en为英文语言,中文语言zh <html lang="en"> <head> < ...
- IDEA 创建文件夹总默认根节点问题解决
上面是文件夹结构显示,如果勾掉,就是按层级显示,空目录不会自动折叠成一行 原文地址;https://blog.csdn.net/huangjunwei6/article/details/7150755 ...
- java 3 接口与多态&输入输出流
接口 中的所有方法都是方法 抽象 使用接口实现多继承 类型的装换 数据成员就变成了static 和 final food 和 snow 都是可以吃的 可以同时实现多个接口 接口与接口之间也可以有继承关 ...
- MaxCompute 构建企业云数据仓库CDW的最佳实践建议
在本文中阿里云资深产品专家云郎分享了基于阿里云 MaxCompute 构建企业云数据仓库CDW的最佳实践建议. 本文内容根据演讲视频以及PPT整理而成. 大家下午好,我是云郎,之前在甲骨文做企业架构师 ...