[Chuanzhi Cup] The 3rd "Chuanzhi Cup" National College Student IT Skills Competition (Preliminary Group A) G-Forest | Collecting and Thinking

Main idea:

Steamed Fish is a dedicated YYH Land forest ranger. He is responsible for daily maintenance of the forest of YYH Land. At the beginning, there was only one tree with nn in YYH LandA tree of n nodes, each node has a spiritual power valuevvv

Since YYH Land is a magical country, the trees of YYH Land also have some magical abilities. Specifically, it satisfies the following operations:

  • 1 e

Numbered eeThe edge of e suddenly disappeared, making the tree it was on into two trees.

  • 2 uuu v a l val val

The spiritual power value of the node numbered uu becomes valval.

  • 3 uuu

The steamed fish made a query to query the sum of the spiritual power of the tree where uu is located.

Now you need to help steamed fish to simulate the above events to understand the changes in the forest.

Question idea:

See the plus side, the operation minus side, to 并查集close on it
as this problem is limited to the border erase, and along with the change in the value of the right
is clear that the border erase operation is not good to maintain the value of spiritual power
, however, edging operation for each The change of the spiritual power value of a piece is very easy to maintain.
Assuming that there is only an edge operation, then for a point x's spiritual power value changes, then the root of a point x (and search for the root) increase newval − lastval newval- lastvalnewvall a s t v a l is all right.
So after considering storing the operation offline, flashback processing (minus side is replaced with added side)
also corresponds to the change of the weight. It is good to
note that before flashback processing, you should save the operation. After the picture权值and the分块situation, then operate on this picture, instead of directlynnOperate on n points

Code:

/*** keep hungry and calm CoolGuang!  ***/
/*#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)*/
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define d(x) printf("%lld\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17;
const ll maxn = 4e5+700;
const int mod= 1e9+7;
const int up = 1e9;
template<typename T>inline void read(T &a){
    
    char c=getchar();T x=0,f=1;while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
    
    x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
int pre[maxn];
ll num[maxn],val[maxn];
pair<int,int>e[maxn];
vector<int>v[maxn];
int vis[maxn];
int Find(int x){
    
    
    return pre[x]==x?x:pre[x] = Find(pre[x]);
}
struct node{
    
    
    int op,x,y;
}q[maxn];
ll res[maxn];
int main(){
    
    
    read(n);read(m);
    for(int i=1;i<=n;i++){
    
    
        read(num[i]);
        val[i] = num[i];
        pre[i] = i;
        v[i].push_back(num[i]);
    }
    for(int i=1;i<=n-1;i++){
    
    
        int x,y;read(x);read(y);
        e[i] = {
    
    x,y};
    }
    for(int i=1;i<=m;i++){
    
    
        read(q[i].op);
        if(q[i].op == 1){
    
    
            read(q[i].x);
            vis[q[i].x] = 1;
        }
        else if(q[i].op == 2){
    
    
            read(q[i].x);
            read(q[i].y);
            v[q[i].x].push_back(q[i].y);
        }else read(q[i].x);
    }
    for(int i=1;i<=n;i++)
        if(v[i].size())
            val[i] = num[i] = v[i].back();
    for(int i=1;i<=n-1;i++){
    
    
        if(vis[i]) continue;
        int dx = Find(e[i].first),dy = Find(e[i].second);
        if(dx != dy){
    
    
            pre[dx] = dy;
            val[dy] += val[dx];
        }
    }
    for(int i=m;i>=1;i--){
    
    
        if(q[i].op == 1){
    
    
            int dx = Find(e[q[i].x].first),dy = Find(e[q[i].x].second);
            if(dx != dy){
    
    
                pre[dx] = dy;
                val[dy] += val[dx];
            }
        }else if(q[i].op == 2){
    
    
            v[q[i].x].pop_back();
            int dx = Find(q[i].x);
            val[dx] += v[q[i].x].back() - num[q[i].x];
            num[q[i].x] = v[q[i].x].back();
        }
        else res[i] = val[Find(q[i].x)];
    }
    for(int i=1;i<=m;i++){
    
    
        if(res[i])
            printf("%lld\n",res[i]);
    }
    return 0;
}

/***
5 7
1 2 3 4 5
1 2
2 3
3 4
4 5

3 1
3 2
2 1 5
1 2
2 1 3
3 1
3 5
****/

Guess you like

Origin blog.csdn.net/qq_43857314/article/details/111680368