首页 > 其他分享 >CF1777D Score of a Tree 题解

CF1777D Score of a Tree 题解

时间:2023-05-13 15:15:22浏览次数:61  
标签:tmp 结点 le int 题解 Tree long Score ans

题目简述

给你一个 \(n\) 个结点根为 \(1\) 的树。在 \(t = 0\) 时,每个结点都有一个值,为 \(0\) 或 \(1\)。

在每一个 \(t > 0\) 时,每个结点的值都会变成其子结点在 \(t - 1\) 时的值的异或和。

定义 \(S(t)\) 为 \(t\) 时所有结点值的和。

定义 \(F(A)\) 为树在 \(0 \le t \le 10^{100}\) 中所有 \(S(t)\) 的和。其中 \(A\) 为树在时刻 \(0\) 时每个结点的值。

求所有 \(2^n\) 个 \(F(A)\) 的和。

思路

引理

引理:设 \(d_i\) 为第 \(i\) 个结点与其子树中结点距离的最大值。如果 \(d_i > t\) 则该结点在 \(t\) 时刻的值为 \(0\) 。如果 \(d_i \le t\) 则该结点在 \(t\) 时刻是 \(1\) 的几率为 \(50\%\) 。

归纳证明:

在 \(t = 0\) 时成立。

假设在 \(t = k\) 时成立。

则在 \(t = k + 1\) 时:

1.如果结点 \(i\) 的任意一子结点 \(u, d_u > k\) 。

\(\because d_i = \max\{d_u\}+1\)

\(\therefore d_i > k + 1\)

2.如果结点 \(i\) 的子结点在 \(t = k\) 时有 \(j\) 个结点有 \(d_u \le k\) 。

所以一共有 \(2^j\) 种选取方法。异或和为 \(1\) 的方案数为 \(C_j^1 + C_j^3 + C_j^5 + \cdots\) 。

\(\because C_j^1 + C_j^3 + C_j^5 + \cdots\)

\(= C_{j-1}^0+C_{j-1}^1+C_{j-1}^2+C_{j-1}^3+C_{j-1}^4+C_{j-1}^5+\cdots+C_{j-1}^{j-1}\)(若 \(j\) 为奇数, \(C_{j-1}^j=0\) )

\(=2^{j-1}\)

\(=2^j\times50\%\)

\(\therefore\) 此时结点 \(i\) 为 \(1\) 的概率为 \(50\%\) 。

证毕

由于 \(d_i \leq n \leq 2\times 10^5 \leq10^{100}\) 。

由于 \(t\) 值很大,所以最后所有结点的值均为 \(0\) 。

根据引理,每个结点对答案的贡献即为 \(2 ^ {n - 1} \times (d_i + 1)\) 。

所以用 DFS 来求 \(d_i\) 即可。

代码

#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
const int N = 2E5 + 5, M = 1E9 + 7;
int n, t;
int u, v;
long long tmp = 0; 
vector<int> G[N];
long long dfs(int u, int f) {
	long long ans = 1;
	for (int v : G[u]) {
		if (v == f) continue;
		ans = max(ans, dfs(v, u) + 1);
	}
	tmp += ans;
	tmp %= M;
	return ans;
}
int main()
{
	cin >> t;
	while (t--) {
		cin >> n;
		for (int i = 1; i <= n; i++) G[i].clear();
		for (int i = 1; i < n; i++) {
			cin >> u >> v;
			G[u].push_back(v);
			G[v].push_back(u);
		}
		long long ans = 1;
		for (int i = 1; i < n; i++) {
			ans *= 2;
			ans %= M;
		}
		tmp = 0;
		dfs(1, 0);
		ans = ans * tmp;
		ans %= M;
		cout << ans << ' ';
	}
}

标签:tmp,结点,le,int,题解,Tree,long,Score,ans
From: https://www.cnblogs.com/easonhe/p/17397414.html

相关文章

  • CF1777C Quiz Master题解
    题目简述给定一个长度为\(n\)的正整数序列\(a\),以及一个正整数\(m\)。在序列\(a\)中选出一个长度为子序列(不是子段)\(b\),\(\foralli\in[1,m],\existsb_j,b_j\)能整除\(i\)。求所有满足条件的序列\(b\)的极差(最大值于最小值的差)的最小值;若无满足条件序列\(b\)......
  • Educational Codeforces Round 148 (Rated for Div. 2) A-D 题解
    比赛地址A.NewPalindrome题意:给一个回文串,判断是否能重新排成另一个回文串Solution存不同对的个数即可voidsolve(){ strings; cin>>s; intn=s.length(); set<char>st; for(inti=0;i<n/2;i++) { st.insert(s[i]); } if(st.size()>1)cout<<"YES\n"; els......
  • 「SDOI2017」数字表格 题解
    4114「SDOI2017」数字表格题解个人评价:好题且套路多算法标签莫比乌斯反演题目难度:2700题面看我分析题面多组数据,每次给出\(n,m\),求解\(\prod_{i=1}^n\prod_{j=1}^mF_{gcd(i,j)}\),其中\(F\)是斐波那契数列问题分析第一眼化出这个式子肯定是一脸懵,毕竟我们现在做的大......
  • 问题解决:TNS-12543: TNS:destination host unreachable
    环境:11.2.0.3ADG(db11g\db11gadg\db11gcas)在自己先前克隆后的环境互相tnsping报错。tnsping本机ok,tnsping其他机器均报错:[oracle@db11g~]$tnspingjingyuTNSPingUtilityforLinux:Version11.2.0.3.0-Productionon13-MAY-202308:09:11Copyright(c)1997,......
  • cf 870div2 abcd题解
    A题,先假设一个res从0开始,判断说谎人的个数用ans表示,如果res==ans则假设成立#include<iostream>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;typedefdoubledb;typedefpair<int,int>PII;constllINF=0x3f3f3f3f;constintN=1e4+10;in......
  • 题解 ABC239F【Construct Highway】
    翻译:给定\(n,m\)和度数数组\(\{d_i\}\),再给你\(m\)条边,请构造一棵\(n\)点的树包含这\(m\)条边,且第\(i\)个点的度数为\(d_i\),或者判断无解。显然,若\(\sumd_i\ne2(n-1)\),则无解。然后对于输入的每条边,使用并查集维护,再求出在这\(m\)条边的基础上每个点还需要多......
  • vi基本入门操作,Ubuntu中vi方向键乱码问题解决方案?
    一、vi基本操作语法:vi+文本名例如创建一个名为text的文本文件进入后先敲击键盘"I"(看个人习惯,敲“a”也是一样的结果,大小写都行),进入插入模式,即可正常输入如果要敲错了内容,和Windows一样,用backspace来删除,也可以用delete键,问题在于用delete键只能删除选中部分的内容,且仅能选......
  • 2023市北区程序设计竞赛题解
    1.分糖果原题: 解题思路:这道题类似于辗转相除法,这道题是辗转相减,每次取余数,如果整除,直接计算答案,并退出,否则继续取余 AC代码:#include<bits/stdc++.h>#definelllonglongusingnamespacestd;intmain(){ lla,b,ans=0;cin>>a>>b; while(a!=b){ if(a<b)swap(a,b......
  • 洛谷 P4544 [USACO10NOV]Buying Feed G - 题解
    https://www.luogu.com.cn/problem/P4544感觉是很没意思的DP+DS优化,以前做过几道更难的题:https://codeforces.com/contest/1788/problem/Ehttps://atcoder.jp/contests/abc288/tasks/abc288_f这种题只要是让我写总是能把代码整的伤痕累累(逃第一眼:我艹不就是一个sbDP吗......
  • 模拟测试题解
    题目链接:https://vjudge.csgrandeur.cn/contest/557480AOJ维护中计算a+b(0<=a,b<=10)。点击查看代码#include<iostream>usingnamespacestd;intmain(){inta,b;cin>>a>>b;cout<<a+b;return0;}B不支持python队列报数,直接模拟即可。点击查看......