首页 > 其他分享 >牛客周赛 Round50 E-小红的树上移动 (期望dp+逆元)

牛客周赛 Round50 E-小红的树上移动 (期望dp+逆元)

时间:2024-07-09 17:09:08浏览次数:11  
标签:Round50 周赛 vis int res 牛客 一层 节点 dp

image

E-小红的树上移动

题目:image

题意:在一个树上从根节点移动,每次都会向更深的下一层走,如果此时已经是叶子节点没有下一层就会停留在这里。求出移动次数的期望,移动次数就是从根节点1开始到此节点的深度。

思路:image

画一个草图不难看出其实在同一层中,到达每个点的概率是一样的。并且,对于每一层的节点概率就是这一层节点个数乘能到达这一层的概率。其中能到达这一层的概率就是到达上一层的概率乘上一层的(非叶子点数/总点数)。

那么,总结一下我们能得到如此的递推关系dp[i]=dp[i-1]*(a-b)/a

dp[i]为到达i+1层的概率,a为总点数,b为叶子点数

那么我们要计算的答案期望就是dp[i-1]乘(b/a)乘d[i],d[i]就是这一层的深度

以下是代码,!注意求逆元时的取模问题

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const int N = 2e6+10;
const int p = 998244353;
int f[N],inv[N],yz[N],dep[N];
int km(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1) res=res*a%p;
		a=a*a%p;
		b>>=1;
	}
	return res;
}
int n,d[N],dp[N],mx=0;
vector<int> h[N];
bool vis[N];
void add(int a,int b)
{
	h[a].push_back(b);
	h[b].push_back(a);
} 
void bfs()
{
	queue<int> q;
	q.push(1);
	vis[1]=1,d[1]=0;
	while(q.size())
	{
		int u=q.front();
		q.pop();
		for(auto v:h[u])
		{
			if(vis[v]) continue;
			vis[v]=1;
			d[v]=d[u]+1;//算出深度 
			dep[d[v]]++;//纪录每个深度点的个数 
            if(h[v].size()==1&&v!=1) yz[d[v]]++;//纪录叶子节点个数 
			mx=max(mx,d[v]);//纪录下最大深度 
			q.push(v);
		}
	}
}
void solve()
{
	cin>>n;
	for(int i=1;i<n;i++) {
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	bfs();
	dp[0]=1;
	int ans=0;
    for(int i=1;i<=mx;i++)//递推求答案过程,注意求逆元时取模 
    {
        int a=dep[i],b=yz[i];
        ans+=i%p*dp[i-1]%p*b%p*km(a,p-2)%p;
        ans%=p;
        dp[i]=dp[i-1]%p*(a-b)%p*km(a,p-2)%p;
        dp[i]%=p;
    }
	cout<<ans<<endl;
}
signed main()
{
	ios;
	int t=1;
	//cin>>t;
	while(t--)
	{
		solve() ;
	}
	return 0;
}

El Psy Congroo" - Okabe Rintaro!

标签:Round50,周赛,vis,int,res,牛客,一层,节点,dp
From: https://www.cnblogs.com/onlypasserby/p/18292335

相关文章

  • 第 405 场周赛
    3210.找出加密后的字符串classSolution{public:stringgetEncryptedString(strings,intk){intn=s.size();stringt=s;for(inti=0;i<n;i++)t[i]=s[(i+k)%n];returnt;}};3211.......
  • 牛客周赛 Round 50 D[小红的因式分解] 超级无敌大暴力
    牛客周赛Round50D小红的因式分解超级无敌大暴力首先拿到这个题,真的是一头雾水,本蒟蒻今天才想出来。。。首先拆开式子,我们可以得到a1a2==a;a1b2+a2b1==b;b1b2==c;那么,我们只需要求解一对a1与b1即可得到本题答案,因为剩下的一对a2b2由a/a1和b/b1得到所以我们可以运用......
  • 牛客周赛 Round 50
    这场还是差点 A.小红的最小最大题意:min(a,b)+x是不是比max(a,b)如果比它大输出YES否则输出NOCode:#include<bits/stdc++.h>usingnamespacestd;intmain(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);inta,b,x;cin>>......
  • 牛客练习赛127
    A、小红的最大价值无聊打一下代码实现#include<bits/stdc++.h>#ifdefLOCAL#include"algo/debug.h"#else#definedebug(...)42#endifintmain(){std::cin.tie(nullptr)->sync_with_stdio(false);#defineintlonglongintn,k;std::c......
  • 牛客练习赛127
    还没补E,感觉很GF。个人感觉质量挺好,拿CFDiv.2来对标也是出的比较好的一场。唯一的缺陷可能是E/F应该换个位置?简要写个题解?A给定数组\(a\),以及常数\(k\),定义\(w(i,j)\)当\(|a_i-a_j|>k\)时候为\(\max(a_i,a_j)\),否则为\(\min(a_i,a_j)\)。显然排序之后贪心将\(w......
  • leetcode404周赛(1,2,3)
    1.三角形的最大高度题意:给你两个整数red和blue,需要用这些求组成一个三角形,相邻行颜色必须不同,求最大高度思路:第一行放一个,第二行放两个第三行放三个,我们可以按奇数偶数行来计算总和,此时有两种情况,先蓝后红,先红后蓝,此时针对于第i行来说,如果先蓝后红此时对应奇偶行的蓝的......
  • 牛客小白月赛97 A-D题解
    AAAAAAAAAAAAAAAAAAAAA-----------------------------题解-------------------------------------------统计数组中有没有出现三个相同的边即可点击查看代码#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;map<int,int>m;int......
  • (对结果分类讨论)牛客周赛 Round 1 C.游游的交换字符
    题意:思路:观察发现相邻元素不同的结果只有两种,要么是101010101...要么是010101010,因此我们可以对结果分类讨论。直接模拟算出两种情况最少需要操作多少次,再取min即可。需要注意的是,如果是奇数串,那么结果只有一种,数量多的一定要放两侧。code:#include<bits/stdc++.h>#includ......
  • 牛客周赛 Round 44
    A题每三张删除一张,n/3就是答案点击查看代码#include<bits/stdc++.h>#defineall(x)(x).begin(),(x).end()#definefifirst#definesesecondusingi64=longlong;usingpii=std::pair<int,int>;template<typenameT>std::vector<T>read(T&n......
  • 牛客周赛 Round 49 (D~F)
    嘤嘤不想求异或喵think:首先l和r的范围有1e18,我们能要到要么是二分(但这题显然和二分无关),所以我们尝试打表找规律.打表发现x是4的倍数,1~x的异或和应该是x,同理其他也是有规律的.#include<bits/stdc++.h>#definefifirst#definesesecond#defineintlonglongusin......