首页 > 其他分享 >P7246 手势密码

P7246 手势密码

时间:2024-06-14 21:10:38浏览次数:20  
标签:int 合并 cin P7246 密码 小点 ans 手势 Generate

Statement:

有一棵 \(n(n \le 3 \times 10^6)\) 个点的树,每个点有点权 \(w_i\)。定义一次操作为选择树上的一条简单路径,并将这条简单路径上的所有点点权减去 \(1\)。
问至少需要多少次操作,使树上所有点的点权恰好变为 \(0\)。

Solution:

对于这样的问题不好入手,则优先考虑转化。

首先将第 \(i\) 个大点拆成 \(w_i\) 个小点,并将这些点都染上颜色 \(i\),我们称两个相同颜色的点为兄弟点。

考虑最坏的情况,显然是需要 \(\sum_{i=1}^nw_i\) 这么多次操作的,平摊到每个小点的贡献就是 \(1\),于是我们考虑一种合并操作。即我们可以通过合并一些小点,使他们的对答案仅仅贡献 \(1\) 次,于是可以消掉一些小点的贡献。容易观察到该过程等价于:

  • 找到一组小点,且这组小点对应的大点组成一条简单路径。

  • 这些小点没有任何一对是兄弟点。

  • 每个点至多连两条边。

最后消掉的贡献 \(ans\) 就是多少条边,换句话说,我们要让边数尽量的大,也就是合并的次数尽量大,并遵循上面的规则。

我们考虑递归解决此问题,假设我们已经到了点 \(u\)。还剩下一些点是未被合并的,这里有一个贪心,我们要让这些点尽量都在这个子问题内合并掉,而不是留给他的父亲去合并。感性理解就是,可能父亲没有这么多点去给你合并,而且如果你废弃了一些点,可能会导致答案变劣。

从而不难设计出一个树形 \(\rm DP\):记 \(f_u\) 是考虑以 \(u\) 为根的子树中,最多的合并次数。我们记 \(a_u\) 是合并完后,\(u\) 还剩下多少个点,\(s_u\) 是 \(u\) 节点最多合并多少次。

显然 \(s_u = \sum_{v \in subtree(u)}{\min(a_u, a_v)}\),\(f_u = \sum_{v \in subtree(v)}f_v + s_u\)。

code:

qwq
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 3e6 + 10;

int n, a[N], f[N], ans;
struct edge{
	int v, next;
}edges[N << 1];
int head[N], idx;

void add_edge(int u, int v){
	edges[++idx] = {v, head[u]};
	head[u] = idx;
}

namespace Generate{
	int n,seed;
	static const int mod=1e9;
	int Rand(int x){
		seed=(1ll*seed*0x66CCF+19260817ll)%x+1;
		seed=(1ll*seed*0x77CCF+20060428ll)%x+1;
		seed=(1ll*seed*0x88CCF+12345678ll)%x+1;
		seed=(1ll*seed*0x33CCCCFF+10086001ll)%x+1;
		return seed;
	}
	void RS(){ //你需要传入三个参数,分别表示点权,一条边的两个端点 
		int cnt=0;
		for(int i=1;i<=n;i++)a[i]=Rand(mod); 
		for(int i=2;i<=n;i++){
			int fa=Rand(i-1);
			cnt++;
			add_edge(fa, i); add_edge(i, fa);
		}
	}
};

void dfs(int u, int fa){
	int sum = 0;
	for(int i = head[u]; i; i = edges[i].next){
		int v = edges[i].v;
		if(v == fa) continue;
		dfs(v, u); f[u] += f[v]; sum += min(a[u], a[v]);
	}
	f[u] += min(a[u] * 2, sum); a[u] -= min(a[u], max(0ll, sum - a[u]));
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int opt; cin >> opt; 
	if(opt == 1){
		cin >> n;
		for(int i = 1; i <= n; i++) cin >> a[i], ans += a[i];
		for(int i = 1; i < n; i++){
			int x, y; cin >> x >> y;
			add_edge(x, y); add_edge(y, x);
		}
	}
	else{
		cin >> Generate::seed >> n;
		Generate::n = n;//记得赋值 
		Generate::RS(); //开始工作 
		for(int i = 1; i <= n; i++) ans += a[i];
	}
	dfs(1, 0);
	cout << ans - f[1];
	
	return 0;
}

标签:int,合并,cin,P7246,密码,小点,ans,手势,Generate
From: https://www.cnblogs.com/little-corn/p/18248596

相关文章

  • 在 Microsoft SQL Server 2012 中,修改密码的方法与 SQL Server 2000 相比有所变化,但基
    在MicrosoftSQLServer2012中,修改密码的方法与SQLServer2000相比有所变化,但基本思路是相似的。以下是几种常见的方法:使用SQLServerManagementStudio(SSMS):这仍然是最常见和推荐的方法。通过打开SQLServerManagementStudio,连接到相应的SQLServer实例,然后......
  • 密码工程-大素数
    任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务利用大整数库(GMP或者OpenSSL),参考《密码工程》p113伪代码实现GenerateLargePrime函数(10‘)在测试代码中产生一个在范围l=2^255至u=2^256-1内的素数。(5‘)用OpenSSL验证你产生的素数是不是正确(5’)提交......
  • 运维shell脚本之测试mysql密码正确与否
    shell脚本实战:测试mysql密码正确与否在迁移过程中,常有批量迁移数据库的情况,因此在割接前,需要批量测试一次割接后的数据库信息是否配置正常,故写了一个shell脚本用于测试数据库密码是否正确有误,具体步骤如下:测试前,需要测试当前服务器是否已安装mysql,可通过命令进行测试:mysq......
  • SSH实践生成密码
    $ssh-keygen-trsa-P''-f~/.ssh/id_rsa$cat~/.ssh/id_rsa.pub>>~/.ssh/authorized_keys$chmod0600~/.ssh/authorized_keys-t:指定生成密钥类型(rsa、dsa、ecdsa等)-P:指定passphrase,用于确保私钥的安全-f:指定存放密钥的文件(公钥文件默认和私钥同目录下,不同的是,存......
  • 密码管理工具Buttercup
     如果你在寻找一款优先考虑本地使用的密码管理器,那么Buttercup 就是一个针对macOS、Linux和Windows的理想选择。如果你不需要云同步功能,但希望寻找一款与KeePass用户体验不同的密码管理器,那么Buttercup将是一个好的替代品。这是一个带有简洁用户界面的跨平台开源密......
  • 基于python-CNN深度学习的手势识别数字-含数据集+pyqt界面
    代码下载:https://download.csdn.net/download/qq_34904125/89379220本代码是基于pythonpytorch环境安装的。下载本代码后,有个requirement.txt文本,里面介绍了如何安装环境,环境需要自行配置。或可直接参考下面博文进行环境安装。深度学习环境安装教程-anaconda-python-pyto......
  • MariaDB忘记密码
    如果您忘记了MariaDB的root密码,可以按照以下步骤来重置密码:停止MariaDB服务:sudosystemctlstopmariadb启动MySQL安全模式,跳过权限表,并以root用户登录:sudomysqld_safe--skip-grant-tables&mysql-uroot在MySQL命令行中,用以下命令刷新权限表,并设置新密码:FLUSHPRIVIL......
  • SQLCMD 密码中的 K8S 秘密用法始终为空
    我试图使用K8Ssecret密码连接到SQL服务器,但无论我使用什么语法或方法,密码总是空的。如果我硬编码密码,则一切正常。我还可以使用此命令在POD中打印密码,它还会返回存储在密码中的密码,因此POD可以实际访问密码。kubectlexec-itpodname--printenvMSS......
  • 【ubuntu】记住gitlab的登录账号密码
    一、场景   当我们拉取多个项目时,每次总要输入密码,http方式的时候  二、方法gitconfig--globalcredential.helperstore然后可以手动配置账号密码配置~/.gitconfig文件[user][email protected][credential]helper=store[f......
  • win10 连接samba 账号密码不正确。但实际上账号密码是对的
    网上解决的办法有很多,分享一个我自己遇到的解决方法(其实是因为之前参考别人修改了这个安全设置,导致能连的上的samba也连不上了)网络安全:LAN管理器身份验证级别问题先win+r输入regedit打开注册表找到下面的这个1、本地安全策略,本地策略-安全选项,需要修改成默认的值的修改方式:查找......