zoukankan      html  css  js  c++  java
  • [2019徐州网络赛J题]Random Access Iterator

    题目链接

    大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率。son[x]为x节点的儿子节点个数。

    又又又又没做出来,心态崩了。

    下来看了官方题解后发觉自己大体思路是没错的,但是细节太弱了Orz。

    大体思路:设dp[x]为以x为根节点,求到达最深深度的概率。先跑一遍dfs,求出每个点的子节点数,每个点的深度以及最深深度。

    我们可以求得从x点一次不能到达最深深度的概率为$cnt =1-( frac{sum_{yepsilon x } dp[y]}{son[x]})$

    则$dp[x]=1-cnt^{son[x]}$为son[x]次能到达最深深度的概率。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 2e6 + 10;
     5 const ll mod = 1e9 + 7;
     6 struct node {
     7     int s, e, next;
     8 }edge[maxn];
     9 int head[maxn], len;
    10 void init() {
    11     memset(head, -1, sizeof(head));
    12     len = 0;
    13 }
    14 void add(int s, int e) {
    15     edge[len].e = e;
    16     edge[len].next = head[s];
    17     head[s] = len++;
    18 }
    19 int mxd[maxn], d[maxn], son[maxn];
    20 ll dp[maxn];
    21 ll qpow(ll a, ll b, ll mod) {
    22     ll ans = 1;
    23     while (b) {
    24         if (b & 1)ans = ans * a % mod;
    25         a = a * a % mod;
    26         b >>= 1;
    27     }
    28     return ans;
    29 }
    30 void dfs(int x, int fa) {
    31     mxd[x] = d[x];
    32     for (int i = head[x]; i != -1; i = edge[i].next) {
    33         int y = edge[i].e;
    34         if (y == fa)continue;
    35         d[y] = d[x] + 1;
    36         son[x]++;
    37         dfs(y, x);
    38         mxd[x] = max(mxd[x], mxd[y]);
    39     }
    40 }
    41 void dfs1(int x, int fa) {
    42     ll sum = 0;
    43     for (int i = head[x]; i != -1; i = edge[i].next) {
    44         int y = edge[i].e;
    45         if (y == fa)continue;
    46         if (mxd[y] == mxd[1]) {
    47             dfs1(y, x);
    48             sum = (sum + dp[y]) % mod;
    49         }
    50     }
    51     if (son[x] == 0)
    52         dp[x] = 1;
    53     else {
    54         ll p = sum * qpow(son[x], mod - 2, mod) % mod;
    55         p = (1 - p + mod) % mod;
    56         dp[x] = (1 - qpow(p, son[x], mod) + mod) % mod;
    57     }
    58 }
    59 int main() {
    60     int n;
    61     scanf("%d", &n);
    62     init();
    63     for (int i = 1; i < n; i++) {
    64         int x, y;
    65         scanf("%d%d", &x, &y);
    66         add(x, y), add(y, x);
    67     }
    68     dfs(1, 0);
    69     dfs1(1, 0);
    70     printf("%lld
    ", dp[1]);
    71 }
  • 相关阅读:
    Java的protect修饰限制
    Java静态导入包
    Java代码块
    Java多态类型转换
    Java中只有值传递!!!
    测试
    编译原理实验-LL1语法分析器(自动生成First集、Follow集求法)java实现
    用面向对象的思维设计相关类,从而实现直线与直线、直线与圆、直线与矩形的交点。
    java常见类库学习(1)String、StringBuilder、StringBuffer
    JAVA —Lock锁
  • 原文地址:https://www.cnblogs.com/sainsist/p/11489858.html
Copyright © 2011-2022 走看看