首页 > 其他分享 >2024牛客暑期多校训练营6 A Cake

2024牛客暑期多校训练营6 A Cake

时间:2024-08-01 22:09:10浏览次数:16  
标签:cnt 1.0 maxn0 int 多校 2024 牛客 NR 节点

题目大意

详细题目传送门
\(A\) 和 \(B\) 要从轮流走,从根到一个叶子节点位置,\(A\) 先。树有边权 \(0,1\) ,按照顺序经过的边权按字符串拼接得到一个串 \(S\)。现在 \(B\)可以把 \(1\) 拆分成任意个分数(但不能超过 \(S\) 的长度,且分数可以为空,)两人按照 \(S\) 串的顺序选取,如果 \(S_i=0\) 则 \(B\) 拿, \(S_i=1\) 则 \(A\) 拿。问 \(A\) 最多能拿多少。

\(2\leq n\leq 2\times 10^5\),\(n\) 为数的大小。

思路

首先先考虑第二部分。发现对于后手来说是十分被动的,对于能拿的希望拿的多一点,但最终能拿多少全部取决于先手。发现双方的利益取悦于找到一个 \(l\) 使得平均分成 \(l\) 份让其中的占比最大。则我们维护树上每一个节点边的最优前缀表示其中走到这里选 \(0\) 和选 \(1\) 的期望占比。其中 \(0\) 要取 \(\max\),\(1\) 要取 \(\min\),因为第二部分的选择权是 \(0\)。

之后就可以考虑博弈,从叶子节点反推,每一次取当前手的子节点对自己最优的,然后最后输出根节点的值即可。

代码

#include <bits/stdc++.h>

using namespace std;
const int NR = 200001;
int n;
vector<pair<int, int> > e[NR];
int cnt[2][NR];
double f[2][NR];
void dfs1(int u, int fa, int m){
	if (m > 0){
		f[0][u] = 1.0 * cnt[0][u] / (1.0 * m);
		f[1][u] = 1.0 * cnt[1][u] / (1.0 * m);
	}
	if (m > 1){
		f[0][u] = max(f[0][u], f[0][fa]);
		f[1][u] = min(f[1][u], f[1][fa]);
	}
    //cout<<u<<" "<<f[0][u]<<" "<<f[1][u]<<endl;
	for (int i = 0; i < e[u].size(); i++){
		int v = e[u][i].first, w = e[u][i].second;
		if (v != fa){
			cnt[0][v] = cnt[0][u];
			cnt[1][v] = cnt[1][u];
			cnt[w][v]++;
			dfs1(v, u, m + 1);
		}
	}
}
void dfs2(int u, int fa, bool flag){
	double maxn0 = -1, maxn1 = -1;
	int id = 0;
    bool leaf=true;
	for (int i = 0; i < e[u].size(); i++){
		int v = e[u][i].first;
		if (v != fa){
			dfs2(v, u, (flag ^ 1));
            leaf=false;
			if (flag){
				if(f[1][v]>maxn1){
                    maxn1=f[1][v];
                    maxn0=f[0][v];
                }
			}
			else{
				if(f[0][v]>maxn0){
                    maxn0=f[0][v];
                    maxn1=f[1][v];
                }
			}
		}
	}
    
    if(!leaf){
        f[0][u]=maxn0;
        f[1][u]=maxn1;
    }
    
    //cout<<u<<" "<<f[0][u]<<" "<<f[1][u]<<endl;
}
void test(){
	cin >> n;
	for (int i = 1; i <= n; i++){
		e[i].clear();
        f[0][i]=f[1][i]=0;
        cnt[0][i]=cnt[1][i]=0;
	}
	for (int i = 1; i < n; i++){
		int u, v, w;
        cin>>u>>v>>w;
		e[u].push_back(make_pair(v, w));
		e[v].push_back(make_pair(u, w)); 
	}
	dfs1(1, 0, 0);
	dfs2(1, 0, true);
    printf("%0.12lf\n",f[1][1]);
}
int main(){
	int T;
	cin >> T;
	while (T--){
		test();
	}	
	return 0;
}

标签:cnt,1.0,maxn0,int,多校,2024,牛客,NR,节点
From: https://www.cnblogs.com/tanghg/p/18337290/solution-2024nk6A

相关文章

  • 喜报 | 极限科技入选北京市 2024 年第一批科技中小企业名单
    2024年7月24日,北京市科学技术委员会、中关村科技园区管理委员会发布《关于北京市2024年第一批拟入库科技型中小企业名单的公示》。根据《科技型中小企业评价办法》(国科发政〔2017〕115号)和《科技型中小企业评价服务工作指引》(国科火字〔2022〕67号)有关规定,极限数据(北......
  • 2024.8 - 做题记录与方法总结
    2024.8-RecordofQuestionsandSummaryofMethodology先分享一个歌单:永无止境的八月!2024/08/01先来点重量级的P4768[NOI2018]归程题面:[NOI2018]归程题目描述本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定。魔力之都可以抽象成一个\(n\)个节......
  • 2024暑假集训测试17
    前言比赛链接。T1没加记忆化莫名原因T飞了,T2没做过IO交互不知道咋测样例干脆没交,T3到现在还不知道为啥爆零了,赛时不知道咋合并背包根本不敢打,离线下来寻思快点结果全死了,T4不可做题。还是老毛病,遇到之前见的不多题型(尤其是T1、T2放)就寄,这次T1倒是没卡住(但是挂分......
  • 2024.8.1 test
    A\(n\)个点的完全图,\(i\toj(i<j)\)的边权是\(u_j-u_i\),问最小生成树。\(n\le3e5\)。考虑boruvka算法。boruvka算法是重复以下过程,直到只有一个连通块。找到所有连通块的连向外面的最小边,并把这些边加入最小生成树。不难发现这是最多做\(\logn\)次的。我们现在考虑......
  • 2024年1月刷题记录
    2024年1月1日【leetcode】1599.经营摩天轮的最大利润题意:你正在经营一座摩天轮,该摩天轮共有4个座舱,每个座舱最多可以容纳4位游客。你可以逆时针轮转座舱,但每次轮转都需要支付一定的运行成本runningCost。摩天轮每次轮转都恰好转动1/4周。给你一个长度为n的......
  • 2024年4月刷题记录
    2024年4月1日【leetcode】2810.故障键盘题意:你的笔记本键盘存在故障,每当你在上面输入字符'i'时,它会反转你所写的字符串。而输入其他字符则可以正常工作。给你一个下标从0开始的字符串s,请你用故障键盘依次输入每个字符。返回最终笔记本屏幕上输出的字符串。2024......
  • 2024年3月刷题记录
    2024年3月1日【leetcode】2369.检查数组是否存在有效划分题意:给你一个下标从0开始的整数数组nums,你必须将数组划分为一个或多个连续子数组。如果获得的这些子数组中每个都能满足下述条件之一,则可以称其为数组的一种有效划分:子数组恰由2个相等元素组成,例如,子......
  • 2024年2月刷题记录
    2024年2月2日【leetcode】1686.石子游戏VI题意:Alice和Bob轮流玩一个游戏,Alice先手。一堆石子里总共有n个石子,轮到某个玩家时,他可以移出一个石子并得到这个石子的价值。Alice和Bob对石子价值有不一样的的评判标准。双方都知道对方的评判标准。给你两个长度为......
  • 2024年7月刷题记录
    2024年7月1日【leetcode】494.目标和题意:给你一个非负整数数组nums和一个整数target。向数组中的每个整数前添加'+'或'-',然后串联起所有整数,可以构造一个表达式:例如,nums=[2,1],可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。......
  • 2024年6月刷题记录
    2024年6月1日【leetcode】2928.给小朋友们分糖果I题意:给你两个正整数n和limit。请你将n颗糖果分给3位小朋友,确保没有任何小朋友得到超过limit颗糖果,请你返回满足此条件下的总方案数。2024年6月2日【leetcode】575.分糖果题意:Alice有n枚糖,其中第i......