D. Li Hua and Tree(set操作)

这篇具有很好参考价值的文章主要介绍了D. Li Hua and Tree(set操作)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Problem - D - Codeforces

D. Li Hua and Tree(set操作)

 

李华有一个有n个顶点和n -1条边的树。树的根是顶点1。每个顶点i的重要性为a。将子树的大小表示为该子树中顶点的数量,将重要性表示为该子树中顶点的重要性之和。将非叶顶点的重子结点表示为具有最大子树大小的子结点。如果存在多个重子,则重子的指数最小。李华想做m个操作:“1 x”(1≤x≤n) -计算根为x的子树的重要性。"2 x"(2≤x≤n) -旋转z的重子。形式上,表示son为a的重子,fa为z的父亲。他想去掉和fa之间的边,并在son和fa之间连接一条边。可以保证z不是根结点,但不能保证z不是叶结点。如果是叶,请忽略该操作。假设你是李华,请解决这个问题。输入第一行包含2个整数n, m (2<n <105, 1 < m <105) -树中的顶点数和操作数。第二行包含n个整数a1, a2,…, an(-10°< ai < 10°)-每个顶点的重要性。接下来的n -1行包含树的边。第i行包含两个整数ui和vi (1 < ui, vi≤n, ui vi) -对应的边。给定的边构成了一棵树。接下来的m行包含操作——每行一个操作。第j个操作包含两个整数tj, 2;(t, E [1,2), 1 S a;<n, xj 1如果t;= 2) -第j次操作。输出对于每个“1 æ”查询,在独立的行中输出答案。例子

Examples

input

Copy

7 4
1 1 1 1 1 1 1
1 2
1 3
2 4
2 5
3 6
6 7
1 6
2 3
1 6
1 2

output

Copy

2
3
3

input

Copy

10 14
-160016413 -90133231 -671446275 -314847579 -910548234 121155052 -359359950 83112406 -704889624 145489303
1 6
1 10
10 8
1 4
3 4
2 7
2 5
3 2
9 8
1 4
2 2
2 4
1 4
1 10
2 10
1 9
1 6
2 8
2 10
1 5
1 8
1 1
2 5

output

Copy

-2346335269
-314847579
-476287915
-704889624
121155052
-1360041415
228601709
-2861484545

题解:

纯模拟,只能说看懂题意就很简单

对于操作1,就是输出子树权值和,

操作2,说的很麻烦,简单来说就是

找到这个节点x的父节点f,找到这个节点x的子节点ne(包含最多子节点的节点,如果最大的有一样的,找标号最小的)

找到后f与x断开,f与ne连边,ne与x连边

对于子树权值和,很好计算,

关键是如何找到这个节点x的子节点ne(包含最多子节点的节点,如果最大的有一样的,找标号最小的)

因此对于每个节点,dfs记录每个子树权值的同时,并且记录子树大小

我们利用set进行存储每个节点的子节点,{-son[x],x}

-son[x],每次可以取出节点最多的子节点,同时set保证了下标从小到大,每次取首位即可

接下来就是维护,三个节点子树权值,子树大小,父节点(麻烦,但是很容易理解,代码中均有体现)

(如果操作2操作的是叶子结点,记得按题中所说的跳过)文章来源地址https://www.toymoban.com/news/detail-411858.html

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define int long long
vector<int> p[100050];
int n,m;
int sum[100050];
int son[100060];
int fa[100050];
int a[100050];
set <PII> d[100050];
void dfs(int x,int la)
{
	sum[x] = a[x];
	son[x] = 1;
	for(auto ne:p[x])
	{
		if(ne == la)
		continue;
		dfs(ne,x);
		sum[x] += sum[ne];
		son[x] += son[ne];
		fa[ne] = x;
		d[x].insert({-son[ne],ne});
	}
}
void solve()
{
	cin >> n >> m;
	for(int i = 1;i <= n;i++)
	{
		cin >> a[i]; 
	}
	for(int i = 1;i < n;i++)
	{
		int l,r;
		cin >> l >> r;
		p[l].push_back(r);
		p[r].push_back(l);
	}
	dfs(1,0);
	while(m--)
	{
		int op,x;
		cin >> op >> x;
		if(op == 1)
		{
			cout << sum[x] <<"\n";
		}
		else
		{
			if(son[x] == 1)
			continue;
			int f = fa[x];
			auto it = d[x].begin();
			int ne = (*it).second;
			d[f].erase({-son[x],x});
			sum[x] -= sum[ne];
			son[x] -= son[ne];
			d[x].erase(*it);
			d[ne].insert({-son[x],x});
			fa[ne] = f;
			fa[x] = ne;
			sum[ne] += sum[x];
			son[ne] += son[x];
			d[f].insert({-son[ne],ne});
		}
	}
}

signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

到了这里,关于D. Li Hua and Tree(set操作)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • D. Paths on the Tree

    Problem - 1746D - Codeforces 思路:先分析一下题意,根据第一条性质,每次只能够从1开始,而第二条性质则表明对于每个节点来说,经过这个节点的子节点的路径条数应该尽量均衡,最大值与最小值相差不能超过1,所以我们考虑,如果当前要选择k个路径,而当前节点有cnt个子节

    2024年02月09日
    浏览(36)
  • Codeforces Round 768 (Div. 1) D. Flipping Range(思维题 等价类性质 dp)

    题目 思路来源 官方题解 洛谷题解 题解 可操作的最短区间长度肯定是gcd,记为g,然后考虑如何dp 考虑g个等价类,每个等价类i,i+g,i+2*g,... 每次翻转长度为g的区间,会同时影响到g个等价类总的翻转的奇偶性, 性质一:只有每个等价类翻的次数奇偶性相同才合法  性质二:此

    2024年01月19日
    浏览(35)
  • Codeforces Round 890 (Div. 2) D. More Wrong(交互题 贪心/启发式 补写法)

    题目 t(t=100)组样例,长为n(n=2000)的序列 交互题,每次你可以询问一个区间[l,r]的逆序对数,代价是 要在的代价内问出最大元素的位置,输出其位置 思路来源 neal Codeforces Round 890 (Div. 2) supported by Constructor Institute D (交互+分治) 附加强 - 知乎 题解 赛中开题顺序大失败没看这个

    2024年02月14日
    浏览(39)
  • CF1120 D. Power Tree 巧妙的图论转化

    传送门 [前题提要]:无 题目描述: 考虑对一个点的子树的所有 叶子节点 进行增减任意值.不难联想到对一个点的子树的 所有节点 增减任意值的做法.所以考虑使用类似于树链剖分的方式将树上修改化为链上区间修改. 考虑记录一个点的所有叶子节点,并且按照 d f s dfs df s 序将其

    2024年02月10日
    浏览(40)
  • Tree of Thoughts: Deliberate Problem Solving with Large Language Models

    本文是LLM系列的文章,针对《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》的翻译。 语言模型越来越多地被部署用于解决各种任务中的一般问题,但在推理过程中仍然局限于token级别的从左到右的决策过程。这意味着他们可能无法完成需要探索、战略前瞻或初始决

    2024年02月11日
    浏览(52)
  • 杭电oj Simple Set Problem 双指针 尺取法 满注释版

    👨‍🏫 题目地址 输入 输出 使用快读,避免使用 Arrays.fill() 按需初始化 避免卡常 🍑 思路

    2024年02月15日
    浏览(62)
  • Codeforces Round 911 (Div. 2) C. Anji‘s Binary Tree (DFS + 树)

    题目 思路:         dfs树的每一条到叶子的路径, 并计算路径中需要修改的个数, 在这些个数中取最小值 注意:         本题中的树是以每个结点的左右孩子是什么的形式给出的, 所以可以不用建树, 只需保存每个结点的左右孩子是什么即可。 代码:

    2024年01月16日
    浏览(43)
  • G. Rudolf and CodeVid-23 codeforces1846G

    Problem - G - Codeforces 题目大意:给出一长度为n的二进制字符串s,和m对二进制字符串e1和e2,,费用为d,s和一对字符串操作后s中是1且e1中也是1的位置会变成0,s中是0,e2中是1的位置会变成1,得到新的s,每对字符串可以操作任意次,问能否使s变成全0字符串 1=n=10;1=m=1000;1=d=

    2024年02月13日
    浏览(29)
  • Codeforces Round 303 (Div. 2)C. Kefa and Park(DFS、实现)

    C. Kefa and Park 求叶节点数量,叶节点满足,从根节点到叶节点的路径上最长连续1的长度小于m 这道题目主要是实现,当不满足条件时直接返回。 到达叶节点后统计答案,用vector存图的话,无向图时,叶节点的边只有一条,也就是 g [ i ] . s i z e ( ) = = 1 g[i].size()==1 g [ i ] . s i ze

    2024年02月19日
    浏览(38)
  • Codeforces Round 169 (Div. 2)C. Little Girl and Maximum Sum(差分、贪心)

    C. Little Girl and Maximum Sum 给q个[l,r]将所有这些区间里面的数相加和最大。 可以进行的操作是任意排列数组 对出现的每个区间内的位置加上1,代表权值 操作完之后求一遍前缀和,得到每个位置的权值 然后贪心的考虑,权值越大,应该分配给该位置的数越大越好这样对答案的贡

    2024年02月21日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包