Li Hua has a tree of n vertices and n−1 edges. The root of the tree is vertex 11. Each vertex i has importance ai. Denote the size of a subtree as the number of vertices in it, and the importance as the sum of the importance of vertices in it. Denote the heavy son of a non-leaf vertex as the son with the largest subtree size. If multiple of them exist, the heavy son is the one with the minimum index.
Li Hua wants to perform m operations:
- "1 x" (1≤x≤n1) — calculate the importance of the subtree whose root is x.
- "2 x" (2≤x≤n2) — rotate the heavy son of x up. Formally, denote sonx as the heavy son of x, fax as the father of x. He wants to remove the edge between x and fax and connect an edge between sonx and fax. It is guaranteed that x is not root, but not guaranteed that x is not a leaf. If x is a leaf, please ignore the operation.
Suppose you were Li Hua, please solve this problem.
Input
The first line contains 2 integers n,m (2≤n≤105,1≤m≤105) — the number of vertices in the tree and the number of operations.
The second line contains n integers a1,a2,…,an(−109≤ai≤109) — the importance of each vertex.
Next n−1 lines contain the edges of the tree. The i-th line contains two integers ui and vi (1≤ui,vi≤n1, ui≠vi) — the corresponding edge. The given edges form a tree.
Next m lines contain operations — one operation per line. The j-th operation contains two integers tj,xj (tj∈{1,2}, 1≤xj≤n1, xj≠1 if tj=2) — the j-th operation.
Output
For each query "1 x", output the answer in an independent line.
思路: dfs把每一个点对应的值加起来在用set维护每个节点的子节点
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
const int N = 1e5 + 10;
int n,m;
int a[N];
vector<int>edge[N];
map<int,int>mp;
class cmp {
public:
bool operator()(const pair<int, int> &a, const pair<int, int> &b) const {
return a.first == b.first?a.second<b.second:a.first>b.first;
}
};
struct NOW{
int fa;
int num;
int ans;
}seg[N];
set<pair<int, int>, cmp> se[N];//如此定义即可
void update(int x,int y)
{
seg[y].fa = x;
se[x].insert({seg[y].ans, y});
seg[x].num += seg[y].num;
seg[x].ans += seg[y].ans;
}
void build(int u)
{
mp[u]++;
for(int i = 0;i < edge[u].size();i ++)
{
if(!mp[edge[u][i]])
{
build(edge[u][i]);
update(u,edge[u][i]);
}
}
}
void solve()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
{
cin >> a[i];
seg[i].num = a[i];
seg[i].ans = 1;
}
for(int i = 1;i < n;i ++)
{
int x,y;
cin >> x >> y;
edge[x].push_back(y);
edge[y].push_back(x);
}
build(1);
for(int i = 1;i <= m;i ++)
{
int op,x;
cin >> op >> x;
if(op == 1)
{
cout << seg[x].num << '\n';
}
else
{
if(se[x].size() == 0)
continue;
int father = seg[x].fa;
auto point = *se[x].begin();
se[father].erase({seg[x].ans, x});
se[x].erase(point);
int res = seg[x].ans - seg[point.y].ans;
seg[point.y].ans = seg[x].ans;
seg[x].ans = res;
se[father].insert({seg[point.y].ans, point.y});
se[point.y].insert({seg[x].ans, x});
seg[point.y].fa = father;
seg[x].fa = point.y;
int sum = seg[x].num - seg[point.y].num;
seg[x].num -= seg[point.y].num;
seg[point.y].num += sum;
}
}
}
signed main()
{
int tt = 1;
//sc(tt);
while(tt--)
{
solve();
}
}