首页 > 其他分享 >P8827 [传智杯 #3 初赛] 森林 题解

P8827 [传智杯 #3 初赛] 森林 题解

时间:2023-02-14 17:33:38浏览次数:40  
标签:传智杯 int 题解 点权 初赛 fa 100001 操作 scanf

题意

有一颗树,每个点有一个点权 \(v\)。现在要对这棵树进行 \(m\) 次以下三种操作之一:

  • 删除一条边。

  • 修改一个点的点权。

  • 查询一个点 \(u\) 所在的树的点权之和。

解题思路

这道题并没有要求在线,容易想到离线倒序操作的想法。

我们先把所有操作进行完之后的情景模拟出来,由于是倒序操作,只有加边没有删边,所以我们用并查集维护。接下来,对于三种操作,我们进行如下操作:

  • 对于第一种操作,我们将点的两个端点所在的树合并。

  • 对于第二种操作,我们将这棵树的点权之和加上原来的点权再减去现在的点权。

  • 对于第三种操作,我们直接将这个点所在的树的点权之和压入答案数组即可。

代码实现

#include <bits/stdc++.h>
using namespace std;
struct node
{
	int opt, e, val, u;
} q[100001];
struct _
{
	int x, y;
} e[100001];
int n, m, sum[100001], fa[100001], ans[100001], tot;
stack<int> change[100001];
bool del[100001];
int find(int x)
{
	if (x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++) scanf("%d", &sum[i]), change[i].push(sum[i]), fa[i] = i;
	for (int i = 1; i < n; i ++) scanf("%d%d", &e[i].x, &e[i].y);
	for (int i = m; i >= 1; i --)
	{
		scanf("%d", &q[i].opt);
		if (q[i].opt == 1)
		{
			scanf("%d", &q[i].e);
			del[q[i].e] = true;
		}
		else if (q[i].opt == 2) 
		{
			scanf("%d%d", &q[i].u, &q[i].val);
			sum[q[i].u] = q[i].val;
			change[q[i].u].push(q[i].val);
		}
		else scanf("%d", &q[i].u);
	}
	for (int i = 1; i < n; i ++)
		if (!del[i])
		{
			int fx = find(e[i].x), fy = find(e[i].y);
			fa[fy] = fx;
			sum[fx] += sum[fy];
		}
	for (int i = 1; i <= m; i ++)
	{
		if (q[i].opt == 1)
		{
			int fx = find(e[q[i].e].x), fy = find(e[q[i].e].y);
			fa[fy] = fx;
			sum[fx] += sum[fy];
		}
		else if (q[i].opt == 2)
		{
			int fx = find(q[i].u), tmp = change[q[i].u].top();
			change[q[i].u].pop();
			sum[fx] += change[q[i].u].top() - tmp;
		}
		else
		{
			int fx = find(q[i].u);
			ans[++ tot] = sum[fx];
		}
	}
	for (int i = tot; i >= 1; i --) printf("%d\n", ans[i]);
	return 0;
}

标签:传智杯,int,题解,点权,初赛,fa,100001,操作,scanf
From: https://www.cnblogs.com/tongyuxin/p/17120316.html

相关文章

  • lg8365题解
    容易发现我们一定会先加后乘,使用调整法可以证明这个结论。并且可以发现除了\(a_i\)值为\(1\)的数外(假设他们的\(a\)值和为\(s\)),其他的数最多只会选\(1\)个做加法操作(设如......
  • Vue项目在ie浏览器中显示空白的兼容性问题解决
    问题:在ie浏览器中页面报错:SCRIPT5022:SecurityError小编也不知道原因是什么,小编是尝试了以下几种方式才显示出来,这里建议大家试试看。1、下载软件包:@babel/polyfill执......
  • elementUI的table表格改变数据不更新问题解决
    问题原因:在Vue实例创建时,以及data赋值时editable并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新。解决方案:1、给data赋值前把editable属......
  • C++奥赛一本通递推题解
    title:C++奥赛一本通刷题记录(递推)date:2017-11-08tags:一本通openjudegecategories:OIC++奥赛一本通刷题记录(递推)2017.11.8Bygwj1139177410斐波那契数列​​op......
  • C++奥赛一本通排序题解
    title:C++奥赛一本通刷题记录(排序)date:2017-11-16tags:一本通openjudegecategories:OIC++奥赛一本通刷题记录(排序)2017.11.16Bygwj1139177410都是拿STL水的…别......
  • C++奥赛一本通刷题高精度题解
    title:C++奥赛一本通刷题记录(高精度)date:2017-11-15tags:一本通openjudegecategories:OIC++奥赛一本通刷题记录(高精度)2017.11.15Bygwj1139177410大整数加法​......
  • CodeVs天梯黄金Gold题解
    title:CodeVs天梯之Golddate:2017-12-28tags:天梯CodesVscategories:OICodeVs天梯之Gold2018.01.04Bygwj2330x01贪心​​均分纸牌​​#include<iostream>usingname......
  • CodeVs天梯钻石Diamond题解
    title:CodeVs天梯之Diamonddate:2017-12-28tags:天梯CodesVscategories:OICodeVs刷题攻略之Diamond2018.1.14Bygwj11391774100x01最短路​​Car的旅行路线​​//1.......
  • CodeVs天梯白银Silver题解
    title:CodeVs天梯之Silverdate:2017-12-28tags:天梯CodesVscategories:OICodeVs天梯之Silver2017.12.18Bygwj11391774100x01排序​​明明的随机数​​#include<iost......
  • CodeVs天梯青铜Bronze题解
    CodeVs天梯之Bronze2017.12.18Bygwj11391774100x01整数处理​​最小数和最大数​​#include<iostream>#include<algorithm>usingnamespacestd;intmain(){intn;c......