首页 > 其他分享 >P11189 「KDOI-10」水杯降温

P11189 「KDOI-10」水杯降温

时间:2024-10-17 22:22:16浏览次数:1  
标签:10 return 最大 int LL KDOI 次数 P11189 节点

P11189 「KDOI-10」水杯降温 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

庆贺吧,第一个真正意义上的自己干出来的紫题。总用时 4h。

时间复杂度 \(O(n\log n)\),对于每个点我们去找它可以吹气的最大次数和最小次数。如果一个点的最小次数大于它的最大次数,或者在计算父节点 u 最大次数时 j 减去的次数大于 j 最大次数,那么不可能成功吹冷。其余情况都可以吹冷。

对于最大次数采用二分验证答案方法,设当前减去的总数为 k,那么 \(m = a[u]\) 就会变成 m - k,一般 k 是大于 m 的,为了让 m 变为 0,需要总体加热 k - m。那么对于子节点来说,这些子节点最多减少 k 次,同时都必须加上 k - m,那么对每一个 j 判断,如果 \(b = a[j]\),b + k - m 如果大于 0,那么 j 就必须减去 s = b + k - m 个,我们就让 k 减去 s,如果 k - s 小于 0,说明我们需要的减不够,那么这种状态就不行,注意,如果 s 超过了 j 的最大次数,也是不行的。不断进行。特别的如果 u 是叶节点,那么它的最大次数无穷大。求出了最大合适的 k 之后需要和子节点最大次数之比对,取比较小的那个最为 u 的最大次数。因为最大不能超过子节点的最大限度。

对于最小次数,则是子节点最小次数之和与当前 \(a[u]\) 中,大的那个。因为需要满足双方最小。

对于最大次数,可以为负数,为了判断如,这种情况:

0
1
2
1
-2 -1
s

综上写出代码即可。较短。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

typedef long long LL;

const int N = 500010;
const LL INF = 1e12 + 10;

int h[N], ne[N], e[N], idx;
int n, m, key = 601;
LL a[N], cnt[N], low[N];

bool check(LL u, LL k)
{
    LL res = k;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        LL s = k - a[u] + a[j];
        if (s > cnt[j]) return false; // 需要减去的不能超过它能承受的最大的
        if (s > 0) res -= s;
        if (res < 0) return false;
    }
    return true;
}

LL find1(LL u)
{
    LL l = -INF, r = INF;
    
    while (l < r)
    {
        LL mid = l + r + 1 >> 1;
        if (check(u, mid)) l = mid;
        else r = mid - 1;
    }
    
    return l;
}

bool dfs(int u)
{
	LL sum = 0, sum2 = 0;
	bool flag = 0;
	for (int i = h[u]; i != -1; i = ne[i])
	{
		int j = e[i];
		if (dfs(j)) return true;
		sum += low[j];
		sum2 += cnt[j];
		flag = true;
 	}
	if (flag) 
	{
	    cnt[u] = min(find1(u), sum2);
	   // cout << 'a';
	   //cout << find1(u) << endl;
	}
	else cnt[u] = INF;
	
	if (flag) low[u] = max(sum, a[u]);
	else low[u] = -INF;
// 	printf("%d %lld %lld\n", u, low[u], cnt[u]);
	if (low[u] > cnt[u]) return true;
	return false;
}

void add(int a, int b)
{
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

int main()
{
	int T;
	cin >> T >> T;
	for (int u = 1; u <= T; u ++ )
	{

		cin >> n;
		idx = 0;
		for (int i = 0; i <= n; i ++ ) 
		{
			h[i] = -1;
		}
		for (int i = 2; i <= n; i ++ ) 
		{
			int x;
			cin >> x;
			add(x, i);
		}
		for (int i = 1; i <= n; i ++ ) 
		{
			scanf("%lld", &a[i]);
		} 
		int flag = dfs(1);
		if (flag) puts("Shuiniao");
		else puts("Huoyu");
	}
	
	return 0;
}


/*
hack

0
1
2
1
-2 -1
s

0
1
7
1 2 2 3 3 5 
21 18 16 -80 14 2 12
s

0
1
7
1 2 2 3 2 3 
1206191 1201814 1172698 -778167 116182 -2139946 1052140 
s

0
1
7
1 2 2 3 3 5 
1347945 1347877 1347443 -536656 1344473 2906 1240697 
s

*/

标签:10,return,最大,int,LL,KDOI,次数,P11189,节点
From: https://www.cnblogs.com/blind5883/p/18473245

相关文章

  • Response & web登录操作 -2024/10/17
    响应行设置响应状态码:voidsetStatus(intsc);设置响应头键值对:voidsetHeader(Stringname,Stringvalue);response实现重定向resp.setStatus(302);resp.setHeader("location","https://www.4399.com");前端a.html登录,将结果传给后端,用request接收,用M......
  • 10.7 模拟赛总结
    T1ZYB建围墙题意给你一个数\(n\),求把这\(n\)个格子围起来所需的格子数的最小值。思路首先,我们尝试把图画出来枚举前面来找出规律。下面这张图里是1~10的距离。好的,我们可以发现。在这个图中7这个图内部是六边形。外面一圈绿色的也是六边形。这个时候我们发现数据中......
  • 2024.10.17
    DATE#:20241017ITEM#:DOCWEEK#:THURSDAYDAIL#:玖月拾伍TAGS<BGM=“呼唤落花之名-MoreanP”><oi-contest><[NULL]><[空]><[空]>我携落花与浪漫给予你,给予温柔本身。距2024CSP-S还有\(\textbf{0x8}\)天!!!比赛主页-20241017高一csp模拟赛A......
  • [10.17]CSP模拟赛
    本场比赛中小L的std挂了样例,所以他需要唱歌~俗话说暴力要打满,但是暴力把数据范围打多了就一点不好了。赛前发现可以提前看题,但是昏昏欲睡的我决定先去睡觉。赛时睡醒了,开题。看到T1,一眼发现一种病毒要不把它所在的矩形全部删除,要不就不用管,所以很自然地想到预处理出每......
  • 2024-10-17
    字体属性颜色大小粗细样式设置元素字体示例点击查看代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0">......
  • P10009 [集训队互测 2022] 线段树
    我们先考虑全局操作的影响。我们对每个位置考虑前面位置对它的贡献,根据差分序列的性质,当你做了\(k\)次异或差分,可以看作每次每个位置贡献给下一行的这一个位置和右侧一个位置,即\(c_{i,j}\toc_{i+1,j},c_{i+1,j+1}\),这个东西显然和杨辉三角等价,贡献方式可以视作每次向下一行......
  • 1017模拟赛
    \(T1\)题面,由于是正方形,我们不需要枚举左上和右下两个端点,只需枚举左上端点和正方形边长,而正方形边长如果用二分枚举,常数大,过不了。这里考虑矩形中一个技巧,即在矩形中充分利用已经求过的信息,故可以想到递推,设\(l[i][j]\)表示\((i,j)\)为左端点最大正方形长度,则\(l[i][j]\)最少为\(......
  • 1016模拟赛
    \(T1\)题面,首先我们先统计能放进自己的桶里的数量,然后我们注意到如果一些数不能放在自己的桶里,它放在其他哪个桶对答案无影响,所以我们看是否有需要放到别的桶里的数比别的所有桶的剩余容量之和,如果有,则\(ans-=\)这个数\(-\)别的桶的剩余容量之和,因为需要把别的桶里一些已经让我们......
  • Aubo Robotics 工业机器人系列编程:i10a_Aubo-i10a安全操作规范
    Aubo-i10a安全操作规范1.安全操作的重要性在工业机器人操作中,安全性是最基本也是最重要的要求。Aubo-i10a工业机器人作为一款高精度、高灵活性的机器人,其安全操作规范不仅关系到机器人的正常运行,更关系到操作人员的人身安全。本节将详细介绍Aubo-i10a工业机器人的安全......
  • k8s-NFS系统配置 20241017
    1、NFS服务端安装-master节点192.168.177.133#安装nfs服务端yuminstallnfs-utils-y#创建共享目录mkdir/nfs#配置nfs共享vim/etc/exports#添加以下一行/nfs*(rw,sync,no_root_squash)#指明共享目录和权限设置 #启动nfs服务,并设置开机启动systemctlstartnfs-ser......