首页 > 其他分享 >HDU7401 流量监控

HDU7401 流量监控

时间:2023-11-05 21:45:41浏览次数:38  
标签:tmp 匹配 int 流量 贡献 add HDU7401 监控 mod

给定一颗 \(n\) 个节点的树。求:

  1. 有多少种匹配 \((a_1,b_{1}),\cdots,(a_{\frac{n}{2}},b_{\frac{n}{2}})\),使得对于每一对匹配 \((u,v)\),点 \(u\) 是点 \(v\) 的祖先。
  2. 对于一组合法匹配,定义其权值为这些匹配的交点个数。对于两组匹配 \((a,b),(c,d)\),它们之间有一个交点当且仅当这四个点在同一条到叶节点的链上且交错排列。求所有匹配的权值和。

答案对 \(998244353\) 取模,\(1 \leq n \leq 2000\)。


第一问是简单的:考虑树形 DP,设 \(f_{u,i}\) 表示当前考虑到点 \(u\),子树内还有 \(i\) 个点未被匹配的方案数,答案就是 \(f_{1,0}\)。转移时我们先对 \(u\) 所有儿子的 \(f\) 背包合并,再考虑 \(u\) 是否往下匹配:

  • \(u\) 往下匹配,那么可以在 \(i\) 个点中任选一个,但这样未匹配的点数会减少 \(1\),即 \(f_{u,i-1} \gets f_{u,i} \times i\)。
  • \(u\) 不往下匹配,那么未匹配的点数增加 \(1\),即 \(f_{u,i+1} \gets f_{u,i}\)。

时间复杂度 \(\mathcal{O}(n^2)\)。

对于第二问,我们考虑把贡献拆成比较方便计算的方式。对于一个交点,我们在其靠近叶子的匹配处统计它的贡献。具体来说,对于当前考虑的点 \(u\),如果我们选择往下匹配某个点 \(v\),那么 \((u,v)\) 路径上还没有被匹配的点就一定会和 \(u\) 的某个祖先匹配,这样会和 \((u,v)\) 产生 \(1\) 的贡献。即若 \(u\) 和 \(v\) 匹配,产生的贡献是 \((u,v)\) 路径上未匹配的点数。

这样就可以 DP 了,设 \(g_{u,i}\) 表示当前考虑到点 \(u\),子树内还有 \(i\) 个点未被匹配,的所有方案的权值和。同时 \(u\) 往下找匹配的时候,我们还需要知道贡献和,因此再设 \(h_{u,i}\) 表示当前考虑到点 \(u\),子树内还有 \(i\) 个点未被匹配的所有方案中,这 \(i\) 个点到根的路径上未被匹配的点数和。

转移时都先将所有儿子的 DP 值背包合并,然后考虑 \(u\) 是否往下匹配:

对 \(g\):

  • \(u\) 往下匹配,那么可以在 \(i\) 个点中任选一个,所有方案的贡献和是 \(i \times g_{u,i} + h_{u,i}\),即 \(g_{u,i-1} \gets i \times g_{u,i} + h_{u,i}\)。
  • \(u\) 不往下匹配,那么贡献不变,即 \(g_{u,i+1} \gets g_{u,i}\)。

对 \(h\):

  • \(u\) 往下匹配。考虑对于某个固定的方案,贡献是如何变化的:\(u\) 在这 \(i\) 个点中任选一个 \(v\) 匹配,减少的贡献可以分成两部分,即 \(v\) 本身产生的贡献,以及对于 \(v\) 子树内所有未被匹配的节点,它们的贡献都会减少 \(1\)。第一类贡献的和显然是 \(h_{u,i}\),而根据子树大小和等于深度和,第二类贡献的和也是 \(h_{u,i}\)。即转移为 \(h_{u,i - 1} \gets h_{u,i} \times (i-2)\)。
  • \(u\) 不往下匹配,那么对于每一种方案,所有 \(i\) 个点的贡献都会增加 \(1\),即 \(h_{u,i+1} \gets h_{u,i} + i \times f_{u,i}\)。

注意一下转移顺序即可。总时间复杂度 \(\mathcal{O}(n^2)\)。

code
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
constexpr int N = 2e3 + 5, mod = 998244353;
bool Mbe;
void add(int &x, int y) {
	x = x + y >= mod ? x + y - mod : x + y;
}
int n;
vector <int> e[N];
int f[N][N], g[N][N], h[N][N], sz[N];
void dfs(int u, int ff) {
	if (ff && e[u].size() == 1) {
		sz[u] = f[u][1] = 1;
		return;
	}
	sz[u] = 0;
	int c = 0;
	for (int i = 0; i < e[u].size(); i++) {
		int v = e[u][i];
		if (v == ff) continue;
		dfs(v, u);
		c++;
		if (c == 1) {
			for (int i = 0; i <= sz[v]; i++) f[u][i] = f[v][i], g[u][i] = g[v][i], h[u][i] = h[v][i];
		} else {
			static int tmp[N];
			for (int i = 0; i <= sz[u]; i++)
				for (int j = 0; j <= sz[v]; j++) {
					add(tmp[i + j], 1LL * g[u][i] * f[v][j] % mod);
					add(tmp[i + j], 1LL * f[u][i] * g[v][j] % mod);
				}
			for (int i = 0; i <= sz[u] + sz[v]; i++) {
				g[u][i] = tmp[i];
				tmp[i] = 0;
			}
			
			for (int i = 0; i <= sz[u]; i++) 
				for (int j = 0; j <= sz[v]; j++) {
					add(tmp[i + j], 1LL * h[u][i] * f[v][j] % mod);
					add(tmp[i + j], 1LL * f[u][i] * h[v][j] % mod);
				}
			for (int i = 0; i <= sz[u] + sz[v]; i++) {
				h[u][i] = tmp[i];
				tmp[i] = 0;
			}
			
			for (int i = 0; i <= sz[u]; i++) 
				for (int j = 0; j <= sz[v]; j++) 
					add(tmp[i + j], 1LL * f[u][i] * f[v][j] % mod);
			
			for (int i = 0; i <= sz[u] + sz[v]; i++) {
				f[u][i] = tmp[i];
				tmp[i] = 0;
			}
		}
		sz[u] += sz[v];
	}

	static int tmp[N];
	for (int i = 0; i <= sz[u]; i++) {
		if (i >= 1) {
			add(tmp[i - 1], h[u][i]);
			add(tmp[i - 1], 1LL * g[u][i] * i % mod);
		}
		add(tmp[i + 1], g[u][i]);
	}
	for (int i = 0; i <= sz[u] + 1; i++) {
		g[u][i] = tmp[i];
		tmp[i] = 0;
	}
	
	for (int i = 0; i <= sz[u]; i++) {
		if (i >= 3) add(tmp[i - 1], 1LL * h[u][i] * (i - 2) % mod);
		add(tmp[i + 1], h[u][i]);
		add(tmp[i + 1], 1LL * f[u][i] * i % mod);
	}
	for (int i = 0; i <= sz[u] + 1; i++) {
		h[u][i] = tmp[i];
		tmp[i] = 0;
	}
	
	for (int i = 0; i <= sz[u]; i++) {
		if (i >= 1) add(tmp[i - 1], 1LL * f[u][i] * i % mod);
		add(tmp[i + 1], f[u][i]);
	}
	for (int i = 0; i <= sz[u] + 1; i++) {
		f[u][i] = tmp[i];
		tmp[i] = 0;
	}
	sz[u] += 1; 
}
void solve() {
	cin >> n;
	for (int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		e[u].emplace_back(v);
		e[v].emplace_back(u);
	}
	dfs(1, 0);
	cout << f[1][0] << " " << g[1][0] << "\n";
	for (int i = 1; i <= n; i++) {
		e[i].clear();
		sz[i] = 0;
		for (int j = 0; j <= n; j++) f[i][j] = g[i][j] = h[i][j] = 0;
 	}
} 
bool Med;
int main() {
//	fprintf(stderr, "%.9lf\n", 1.0 * (&Mbe - &Med) / 1048576.0);
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int t; cin >> t;
	while (t--) solve();
//	cerr << 1e3 * clock() / CLOCKS_PER_SEC << "ms\n";
	return 0; 
}

标签:tmp,匹配,int,流量,贡献,add,HDU7401,监控,mod
From: https://www.cnblogs.com/came11ia/p/17811024.html

相关文章

  • 智慧工厂LiteCVR安防视频监控系统方案设计
    在现代化企业中,工厂需要实施视频监控系统。为保障车间财产安全并提高生产效率,需要进行全面的监管,在企业厂区门口、厂房、办公楼、周界围墙、仓库、重要设备等目标进行实时全天候视频监控。视频监控系统采用前端视频数据采集设备即监控摄像头将现场画面转化成电子信号传输至中心,再通......
  • 2.1k star,推荐一个远程监控和管理 PC 的工具
    可以直观的看下界面:可以去体验demo,开源地址在文末:TacticalRMM是一个远程监控和管理工具,由Django,Vue和Go构建。它使用一个用golang编写的代理,并与MeshCentral集成。这个工具可以让用户远程控制、监控和管理Windows,Linux和Mac的设备,提供诸如远程桌面、远程命......
  • 监控易:实时掌握IT设备的健康状况和性能表现
      在当今的数字化时代,IT设备是企业运营的重要支撑,无论是服务器、路由器、交换机、防火墙还是PC、打印机、摄像头等,都承载着各种业务和服务。如果这些设备出现故障或性能下降,就会影响企业的正常运作,甚至造成重大损失。因此,对IT设备进行有效的监控和管理,是每个企业都必须面对的挑......
  • prometheus添加自定义监控与告警(etcd为例)
    一、步骤及注意事项(前提,部署参考部署篇)一般etcd集群会开启HTTPS认证,因此访问etcd需要对应的证书使用证书创建etcd的secret将etcd的secret挂在到prometheus创建etcd的servicemonitor对象(匹配kube-system空间下具有k8s-app=etcd标签的service)创建service关联被监控对象二、......
  • 安全运营之Zeek开源网络流量分析工具安装部署
    一、zeek简要介绍    Zeek官方网站为https://zeek.org/,官网将其定义为一款开源的网络安全流量分析工具,其前身为Bro,在其官方网站可以找到详细的文档说明,zeek可以以单节点部署,也可以以集群的方式部署。Zeek的架构如下:其中有两个关键的组件,EventEngine以及PolicyScriptInter......
  • 脉冲除尘器数据采集在线监控系统如何实现
    脉冲除尘器是一种利用脉冲喷吹清灰技术对气体进行过滤和净化的设备。它主要由箱体、袋室、滤袋、脉冲阀、气泵等组成,具有除尘效率高、净化效果好、操作简便等优点,广泛应用于冶金、建材、化工、电力、农业等领域,如矿山、水泥、钢铁、石灰、石膏、粮食等生产过程中的除尘工作。 通过......
  • 基于PLC控制的粮食脱粒机设备如何实现故障监控与高效运维
    粮食脱粒机广泛应用于农业、粮食加工等领域,如小麦、玉米、大豆等作物的脱粒,是一种用于将谷类作物脱粒脱壳,并对粮食进行清理和筛选的机械设备。 传统的粮食脱粒依靠人力工作,存在劳动强度大、工作效率差、粮食损耗高等问题,随着PLC逐渐应用到粮食机械中,为农业带来便捷的管理方式与更......
  • 造纸机数据采集远程监控物联网解决方案
    自动造纸机是纸张加工工业中应用最广泛的一种机器,它通过将原纸在水中进行浸泡、表面涂布、压榨、干燥等工序制成纸浆,再将纸浆进行成型、压光等工序,最终形成成品纸的机器,具备生产效率高、产品质量好、操作便捷等优点。 为实现多台设备的集中监控管理,物通博联提供基于工业智能网关的......
  • 液压设备远程监控运维管理系统解决方案
    液压设备是利用液体的压力进行能量传递和控制的设备。液压设备通常由液压泵、液压缸、液压控制阀、管路和油箱等组成。在数字化车间的生产线中,通常接入PLC进行自动化控制,实现液压动力的精准供给,广泛应用于工业、制造业、建筑业、交通、军事等领域,如机床、工程机械、船舶等。对设备......
  • 善用Smart Feed,跨境电商商家能够获得更多流量及转化
    对跨境电商商家来说,流量和转化是需要长期关注的内容。尤其在存量市场的不断减少的今天,店铺更需要高质量的运营,才能获得更多流量与转化,在激烈的竞争中顺利脱颖而出。而为了帮助跨境电商商家提高销量,SHOPLINE推出了SmartFeed管理工具,让跨境电商商家在竞争中快人一步。Smart......