Random Access Iterator 徐州网络赛(树形dp)

Random Access Iterator

\[
Time Limit: 4000 ms \quad Memory Limit: 262144 kB
\]

题意

给出伪代码,问按着伪代码在树上跑,能够正确求出来树的深度的概率。

思路

先在树上 \(dfs\) 一遍,求出每个点可以走到的最深深度,用 \(deep\) 表示。
令 \(dp[i]\) 表示从 \(i\) 节点能够正确求出最深深度的概率。

  1. 如果 \(deep[u]\) 不等于最深深度,那么明显 \(dp[u]=0\)
  2. 如果 \(deep[u]\) 是最深深度而且走到了叶子节点,那么 \(dp[u]=1\)
  3. 其他情况,能够走到最深深度的概率 = \(1\) - 每次走每个点都不能走到最深深度的概率,用表达式表达就是,\(sz\) 表示当前节点可以走的其他节点数,特别注意 \(u=1\) 的情况就可以了。
    \[
    dp[u] = 1-\left(\frac{\sum_{v}(1-dp[v)}{sz-1}\right)^{sz-1}
    \]
/***************************************************************
    > File Name    : a.cpp
    > Author       : Jiaaaaaaaqi
    > Created Time : Wed 11 Sep 2019 02:48:22 PM CST
 ***************************************************************/

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e6 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

int maxdeep;
vector<int> vv[maxn];
int deep[maxn];
ll dp[maxn];

ll fpow(ll a, ll b) {
    ll ans = 1;
    while(b) {
        if(b&1) ans = ans*a%mod;
         a = a*a%mod;
         b >>= 1;
    }
    return ans;
}

void dfs(int u, int fa, int d) {
    deep[u] = d;
    for(auto v : vv[u]) {
        if(v == fa) continue;
        dfs(v, u, d+1);
        deep[u] = max(deep[u], deep[v]);
    }
    maxdeep = max(maxdeep, deep[u]);
}

void solve(int u, int fa) {
    if(deep[u] != maxdeep) {
        dp[u] = 0;
        return ;
    }
    if(vv[u].size() == 1) {
        dp[u] = 1;
        return ;
    }
    int sz = vv[u].size()-1;
    if(u == 1)  sz++;
    ll ans = 0;
    for(auto v : vv[u]) {
        if(v == fa) continue;
        solve(v, u);
        ans += (1-dp[v]+mod);
        ans %= mod;
    }
    ans = ans*fpow(sz, mod-2)%mod;
    ans = fpow(ans, sz);
    dp[u] = (1-ans+mod)%mod;
}

int main() {
    // freopen("in", "r", stdin);
    scanf("%d", &n);
    for(int i=1; i<=n; i++) {
        vv[i].clear();
    }
    for(int i=1; i<n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        vv[u].pb(v);
        vv[v].pb(u);
    }
    maxdeep = 0;
    dfs(1, 0, 1);
    solve(1, 0);
    printf("%lld\n", dp[1]);
    return 0;
}

原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/11506438.html

时间: 2024-11-09 15:39:19

Random Access Iterator 徐州网络赛(树形dp)的相关文章

HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过所需要的花费.现在需要你在树上选择两个点,一个作为买入商品的点,一个作为卖出商品的点,当然需要考虑从买入点到卖出点经过边的花费.使得收益最大.允许买入点和卖出点重合,即收益最小值为0. 解法:我们设1为根节点,假设一开始一个人身上的钱为0.我们设dp[i][0]表示从根节点走到i及其子树并中任一点买

hdu 4274 2012长春赛区网络赛 树形dp ***

设定每个节点的上限和下限,之后向上更新,判断是否出现矛盾 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10

2019徐州网络赛 I J M

I. query 比赛时候没有预处理因子疯狂t,其实预处理出来因子是\(O(nlog(n))\)级别的 每个数和他的因子是一对偏序关系,因此询问转化为(l,r)区间每个数的因子在区间(l,r)的个数 预处理出来每个位置上的数所有因子的位置,用可持久化线段树维护,区间询问 #include<bits/stdc++.h> #define ll long long #define mk make_pair #define ft first #define se second #define pii

20180909徐州网络赛题解

目录 20180909徐州网络赛题解 A. Hard to prepare MEANING SOLUTION CODE B. BE, GE or NE MEANING SOLUTION CODE F. Features Track CODE G. Trace MENING SOLUTION CODE H. Ryuji doesn't want to study MEANING CODE I. Characters with Hash CODE J. Maze Designer MEANING S

2018 ICPC 徐州网络赛

2018 ICPC 徐州网络赛 A. Hard to prepare 题目描述:\(n\)个数围成一个环,每个数是\(0\)~\(2^k-1\),相邻两个数的同或值不为零,问方案数. solution 将环变成链,设\(f[i][0\)~\(2]\),分别表示与第一个数相同,与第一个数不同,与第一个数相同,与第一个数的反相同.然后\(dp\)即可. 时间复杂度:\(O(n)\) B. BE, GE or NE solution 根据题目描述\(dp\)即可. 时间复杂度:\(O(nm)\) C.

2018徐州网络赛H. Ryuji doesn&#39;t want to study

题目链接: https://nanti.jisuanke.com/t/31458 题解: 建立两个树状数组,第一个是,a[1]*n+a[2]*(n-1)....+a[n]*1;第二个是正常的a[1],a[2],a[3]...a[n] #include "bits/stdc++.h" using namespace std; #define ll long long const int MAXN=1e5+10; ll sum[MAXN],ans[MAXN]; ll num[MAXN];

ACM-ICPC 2018徐州网络赛-H题 Ryuji doesn&#39;t want to study

C*M....死于update的一个long long写成int了 心累 不想写过程了 ******** 树状数组,一个平的一个斜着的,怎么斜都行 题库链接:https://nanti.jisuanke.com/t/31460 #include <iostream> #include <cstring> #define ll long long #define lowbit(x) (x & -x) using namespace std; const int maxn =

2019徐州网络赛 XKC&#39;s basketball team 线段树

网址:https://nanti.jisuanke.com/t/41387 题意: 大家好,我是训练时长两年半的个人练习生蔡徐坤,我的爱好是唱,跳,rap,篮球. 给出一段长度为$n,(n \leq 1e5)$的序列,对每一个数,求出它和它后面比它大$m$的数中间夹着的数的数量,没有输出$-1$. 题解: 直接建线段树,维护最大值,然后查询时对第$i$个数,搜索区间$[i,n]$之中大于$num[i]+m$的值的位置的最大值,具体操作是先限定区间,然后求出所有合法位置,取最大值,如果搜索不到则返

ICPC2018徐州网络赛 Hard to prepare(dp)

Hard to prepare 28.63% 1000ms 262144K After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a Nogaku show during the feast. To enjoy the show, every audience has to wear a Nogaku mask, and seat around as a