首页 > 其他分享 >NOIP模拟赛 蚊子 mosquito

NOIP模拟赛 蚊子 mosquito

时间:2022-10-02 22:48:13浏览次数:76  
标签:cnt NOIP int 灭蚊器 sum 蚊子 mosquito mod

蚊子

描述

作为一只明媚的兔子,要会叠被子,又得会打蚊子……

兔子住在兔子洞里。兔子洞可以看成是一棵无根树,有 \(n\) 个洞穴,有 \(n-1\) 条通道连接着 \(n\) 个洞穴。每天晚上,兔子会在 \(1\) 号洞穴里缩成一团,睡一觉。同时,蚊子大军出动,去欺负兔子。

因为蚊子人多势众,所以它们分兵 \(m\times (m-1)\) 路。\(m\) 是整个兔子洞中只和一条通道相邻的洞穴数目。任意两个这样的洞穴 \(a,b\) 之间(也就是任意两个叶子节点之间)会有两只蚊子,一只从 \(a\) 飞到 \(b\),一只从 \(b\) 飞到 \(a\)。它们都沿着 \(a\) 到 \(b\) 的最短路径移动。蚊子每秒钟可以通过一条通道。所有蚊子都在 \(0\)s 时突然出现在起点并开始移动。每只蚊子在到达终点后的一瞬间都会突然消失。有些蚊子并不会经过兔子所在的 \(1\) 号节点,它们起到的是恐吓作用。

又一次满脸是包地醒来后,兔子忍无可忍了,于是它找到 lrd,让 lrd 去打蚊子……lrd 不知所措,于是去某宝搞了一个灭蚊器……这个灭蚊器被放在 \(1\) 号节点。每个时刻,它都会工作一次,把和灭蚊器距离小于等于 \(d\) 范围内的蚊子全部杀死。(\(d=0\) 时只能控制 \(1\) 号点一个位置)

遗憾的是,兔子洞尚未通电,兔子只能用爱发电。 因此,每个时刻灭蚊器只有 \(\frac{p}{q}\) 的概率能够正常工作。如果不能正常工作,那么蚊子将不受到任何影响。

灭蚊器无法影响出现之前和消失之后的蚊子。但在蚊子出现在起点和消失在终点的
那个时刻,如果灭蚊器正常工作且蚊子在作用范围内,这只蚊子仍会被杀死。

兔子对 lrd 的诚意表示怀疑……于是它让 lrd 算出灭蚊器在一晚上期望能杀死多少蚊子。lrd 当然会算了,但是他想考考你。因为兔子讨厌小数,你需要输出这个期望值模 \(10^9+7\) 后的结果。即:表示为分子乘分母的逆元(对 \(10^9+7\) 取模)。
(如果你算错了,就会被 lrd 拿去喂兔子,啊呜~~)

格式

输入

第一行一个整数 \(n\),表示兔子洞中洞穴的个数。洞穴编号为 \(1\) 到 \(n\) 的整数。
接下来 \(n-1\) 行,每行两个整数 \(u,v\),表示 \(u\) 和 \(v\) 两个洞穴之间有一条通道。
接下来一行三个整数 \(d,p,q\),表示灭蚊器的作用范围是 \(d\),每个时刻工作的概率是 \(\frac{p}{q}\)。

输出

一行一个整数,你的答案。

样例

输入

3
1 2
1 3
1 1 2

输出

750000007

范围

编号 分值 特殊性质
\(1\) \(15\) \(d=0\)
\(2\) \(25\) \(p=q\)
\(3\) \(60\)

对于所有测试点:

\(m<n\le 5000000,0\le d\le n,1\le p\le q\le 10^9+7\)

本文参考了 这篇题解 的思路,有不少补充。本文的代码与那篇题解的代码有不少相似之处,有不少细节改动。

解析

树形 DP 以及树上路径的好题。这个题目的部分分很有帮助价值。

先考虑 \(d=0\) 的情况,即只有根节点被灭蚊器控制。记 \(cnt_x\) 表示以 \(x\) 为根的子树的叶节点数量。令

\[sum=\sum_{i\in son_1} cnt_i \]

\(son_i\) 表示 \(i\) 的子节点的集合。答案就是

\[\sum_{i\in son_1} cnt_i\times (sum-cnt_i) \]

相当于,把根作为 LCA 折点,对于每一棵子树,都贡献了这棵子树叶子个数与非这棵子树叶子个数的乘积,相当于乘法原理的匹配。至于蚊子双向活动的问题,\(i\) 刷过一遍,每个叶子会在 \((sum-cnt_i)\) 中刷到,也会在 \(cnt_i\) 中刷到。乘上灭蚊器消杀概率即可。

再考虑满分做法。记录动态规划数组 \(f\),\(f_i\) 表示所有蚊子在以 \(i\) 为根的子树里存活期望。同样的,令 \(w\) 为灭蚊器消杀概率:

\[sum=\sum_{v\in son_u} f_v \]

\[tot=\sum_{v\in son_u} cnt_v \]

以 \(u\) 为根的子树的贡献是:

\[\sum_{v\in son_u} cnt_v\times (tot-cnt_v)-f_v\times w\times (sum-f_v) \]

还有一些细节。比如,题目中的分数取模,相当于乘上分母的逆元。灭蚊器消杀概率为 \(\frac{p}{q}\),留蚊子活路的概率是

\[1-\frac{p}{q}=\frac{q-p}{q} \]

可以全开 long long。

代码

// mosquito
#include <bits/stdc++.h>
#define int long long
#define SIZE 1000010
#define all(x) x.begin(), x.end()
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;

int f[SIZE]={0}, dep[SIZE]={0}, cnt[SIZE]={0};
vector<int> a[SIZE]; int n, d;
int inv;
const int mod=1e9+7;

int val(int a, int b)
{
	if(b==0) return 1%mod;
	a%=mod;
	int t=val(a, b/2);
	if(b%2==0)
		return t*t%mod;
	return t*t%mod*a%mod;
}

void dfs(int u, int fa)
{
	dep[u]=dep[fa]+1;
	bool leaf=1;
	for(int v:a[u])
	{
		if(v==fa) continue;
		leaf=0;
		dfs(v, u);
		cnt[u]+=cnt[v];
		if(dep[u]<=d+1) f[u]=(f[u]+f[v]*inv%mod)%mod;
		else f[u]=(f[u]+f[v])%mod;
	}
	if(leaf)
	{
		cnt[u]=1;
		if(dep[u]<=d+1) f[u]=inv;
		else f[u]=1;
	}
}

int ans=0;
void calc(int u, int fa) 
{
	if(dep[u]>d+1) return;
	int sum=0, tot=0;
	for(int v:a[u])
	{
		if(v==fa) continue;
		sum=(sum+f[v])%mod; tot=(tot+cnt[v])%mod;
	}
	for(int v:a[u])
	{
		if(v==fa) continue;
		ans=(ans+cnt[v]*(tot-cnt[v]+mod)%mod-(sum-f[v]+mod)*f[v]%mod*inv%mod+mod)%mod;
		calc(v, u);
	}
}

signed main()
{
	freopen("mosquito.in", "r", stdin);
	freopen("mosquito.out", "w", stdout);
	scanf("%lld", &n);
	for(int i=1; i<n; i++)
	{
		int u, v; scanf("%lld %lld", &u, &v);
		a[u].push_back(v);
		a[v].push_back(u);
	}
	int p, q; scanf("%lld %lld %lld", &d, &p, &q);
	inv=(q-p)*val(q, mod-2)%mod;
	dfs(1, 0);
	calc(1, 0);
	printf("%lld", ans);

    return 0;
}

标签:cnt,NOIP,int,灭蚊器,sum,蚊子,mosquito,mod
From: https://www.cnblogs.com/jerrywang2009/p/16749652.html

相关文章

  • 国庆 NOIP 模拟赛 Day 1
    国庆NOIP模拟赛Day1T1挺简单的一道题,但是读题读了老半天。。输入的是通关的顺序,并且因为每次选择的是满足条件的关卡中编号最小的,所以这个顺序一定是字典序最小的......
  • 10.1 noip 模拟赛
    10.1noip模拟赛目录10.1noip模拟赛\(\to\rmlink\leftarrow\)\(\rmT1\)猜道路\(\rmT2\)简单环\(\rmT3\)汉明距离\(\rmT4\)勇者的后缀\(\to\rmlink\left......
  • [NOIP2011 提高组] Mayan 游戏
    DescriptionlinkSolution令当当前棋盘为\(a\)。注意到\(n\leq5\)且棋盘是\(5\times7\)的,所以直接爆搜可以做到\(O(35^5)=O(52521875)\),然而这里还有很大的常数......
  • NOIP冲刺 【图论复习】 图的遍历
    还有两个月就NOIP了我居然还在敲这种东西.........洛谷P5318DFSBFS模版题复习一下DFS:从第一个节点开始搜用vis数组记忆化搜到每一个点时如果没搜过就把他标记......
  • CSP-S 2022进不去NOIP记
    初赛Day0过了。9.26day-OP414报了qbxt腾飞的线上。9.28day-NP414明天放假!9.30day-ZP414这才过了一半,事倒是很多...早上五点多爬起来打游戏,打完之后看手机突......
  • P2671 [NOIP2015 普及组] 求和(洛谷前缀和
    P2671[NOIP2015普及组]求和1//(x+z)*(num[x]+num[z])=2//(x1+x2)*(y1+y2)+(x1+x3)*(y1+y3)+(x2+x3)*(y2+y3)3//=x1*(y1*(n-2)+y1+y2+...+yn)4//+x2*(y2*......
  • P1040 [NOIP2003 提高组] 加分二叉树
    区间dp好题!在更新\(f[i][j]\)时,顺便记录该子树的根节点\(g[i][j]\)。最后递归求解。#include<bits/stdc++.h>usingnamespacestd;classsolve{ public: int......
  • P3960 NOIP2017 提高组 列队
    P3960NOIP2017提高组列队将每一行的第1到m-1个和第m列分离出来分析知这n+1个“区间”要维护弹出第k个和插入最后使用平衡树,一个区间若没有被算则用[l,r]表示(方伯伯......
  • P1600 [NOIP2016 提高组] 天天爱跑步
    P1600NOIP2016提高组天天爱跑步LCA+桶点击查看代码///*考虑上行的情况(u,v)中u被i看到<=>1.u∈{i的子树} 2.lca(u,v)不属于{i的子树} 3.de......
  • luogu P1043 [NOIP2003 普及组] 数字游戏
    [NOIP2003普及组]数字游戏题目描述丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容......