首页 > 其他分享 >P3178 [HAOI2015]树上操作

P3178 [HAOI2015]树上操作

时间:2022-10-29 17:13:24浏览次数:41  
标签:P3178 cz int mid dfs HAOI2015 mson vt 树上

#include<iostream>
using namespace std;
#define int long long
const int N = 100000 + 1 ;
int n , m , a [ N ] ;
struct node {
    int tag , sum;
};
node tree [ N << 2 ] ;
namespace xds {
    void build ( int k , int l , int r )
    {
        tree [ k ] . tag = - ( 1 << 30 ) ;
        if ( l == r ) {
            tree [ k ] . sum = a [ l ];
            return;
        }
        int mid = l + r >> 1 ;
        build ( k << 1 , l , mid ) ;
        build ( k << 1 | 1 , mid + 1 , r ) ;
        tree [ k ] . sum = tree [ k << 1 ] . sum + tree [ k << 1 | 1 ] . sum ;
        return;
    }
    void push_down ( int k , int l , int mid , int r )
    {
        if ( tree [ k ] . tag == - ( 1 << 30 ) )
            return;

        if ( tree [ k << 1 ] . tag != - ( 1 << 30 ) )
            tree [ k << 1 ] . tag += tree [ k ] . tag;
        else
            tree [ k << 1 ] . tag = tree [ k ] . tag;
        if ( tree [ k << 1 | 1 ] . tag != - ( 1 << 30 ) )
        tree [ k << 1 | 1 ] . tag += tree [ k ] . tag;
        else
            tree [ k << 1 | 1 ] . tag = tree [ k ] . tag;

        tree [ k << 1 ] . sum += ( mid - l + 1 ) * tree [ k ] . tag ;
        tree [ k << 1 | 1 ] . sum += ( r - mid ) * tree [ k ] . tag ;

        tree [ k ] . tag = - ( 1 << 30 ) ;
        return ;
    }
    void update ( int k , int l , int r , int x , int y , int z )
    {
        if ( l >= x && r <= y )
        {
            tree [ k ] . sum += ( r - l + 1 ) * z ;
            if ( tree [ k ] . tag != - ( 1 << 30 ) )
                tree [ k ] . tag += z;
            else
                tree [ k ] . tag = z;
            // cout << tree [ k ] . tag << endl;
            return;
        }
        int mid = l + r >> 1 ;
        push_down ( k , l , mid , r ) ;
        if ( x <= mid ) update( k << 1 , l , mid , x , y , z );
        if ( y > mid ) update ( k << 1 | 1 , mid + 1 , r , x , y , z );
        tree [ k ] . sum = tree [ k << 1 ] . sum + tree [ k << 1 | 1 ] . sum;
        return;
    }
    int query ( int k , int l , int r , int x , int y )
    {
        if ( l >= x && r <= y )
            return tree [ k ] . sum ;
        int mid = l + r >> 1 ;
        push_down ( k , l , mid , r ) ;
        int rhs = 0 ;
        if ( x <= mid ) rhs += query ( k << 1 , l , mid , x , y );
        if ( y > mid ) rhs += query ( k << 1 | 1 , mid + 1 , r , x , y );
        return rhs ;
    }
}int cnt , h [ N ] , to [ N * 2 ] , nt [ N * 2 ];
int value [ N ] , dep [ N ] , fa [ N ] , top [ N ] , mson [ N ] , siz [ N ] ;
int vt [ N ] , num ;
void merge ( int x , int y )
{
    nt [ ++ cnt ] = h [ x ] ;
    h [ x ] = cnt;
    to [ cnt ] = y;
    return ;
}
void dfs_1 ( int x , int father )
{
    dep [ x ] = dep [ father ] + 1;
    fa [ x ] = father;
    siz [ x ] = 1;
    int maxsize = -1;
    for ( int i = h [ x ] ; i ; i = nt [ i ] )
    {
        int y = to [ i ];
        if ( y == father ) continue;
        dfs_1 ( y , x );
        siz [ x ] += siz [ y ];
        if ( siz [ y ] > maxsize ) maxsize = siz [ y ] , mson [ x ] = y ;
    }
    return ;
}
void dfs_2 ( int x , int topfa )
{
    top [ x ] = topfa;
    vt [ x ] = ++ num;
    a [ num ] = value [ x ] ;
    if ( mson [ x ] ) dfs_2 ( mson [ x ] , topfa );
    for ( int i = h [ x ] ; i ; i = nt [ i ] )
    {
        int y = to [ i ];
        if ( y == fa [ x ] || y == mson [ x ] )
            continue;
        dfs_2 ( y , y ) ;
    }
    return ;
}
void cz_1 ( int x , int z )
{
    xds :: update ( 1 , 1 , n , vt [ x ] , vt [ x ] + siz [ x ] - 1 , z ) ;
}
int cz_2 ( int x )
{
    int ans = 0 ;
    while ( top [ x ] != 1 ) {
        ans += xds :: query ( 1 ,1 , n , vt [ top [ x ] ] , vt [ x ] ) ;
        // cout << top [ x ] << " " << x << endl;
        x = fa [ top [ x ] ] ;
    }
    ans += xds :: query ( 1 , 1 , n , 1 , vt [ x ] ) ;
    return ans ;
}
void cz_3 ( int x , int z )
{
    xds :: update ( 1 , 1 , n , vt [ x ] , vt [ x ] , z ) ;
}
signed main ( ) {
    // freopen ( "text.in" , "r" , stdin ) ;
    // freopen ( "text.out" , "w" , stdout ) ;
    cin >> n >> m ;
    for ( int i = 1 ; i <= n ; i ++ )
        cin >> value [ i ] ;
    for ( int i = 1 ; i < n ; i ++ ) {
        static int x , y;
        cin >> x >> y ;
        merge ( x , y ) , merge ( y , x ) ;
    }
    dfs_1 ( 1 , 0 ) ;
    dfs_2 ( 1 , 1 );
    xds :: build ( 1 , 1 , n ) ;
    for ( int i = 1 ; i <= m ; i ++ ) {
        static int op , x , a , y ;
        cin >> op;
        if ( op == 1 ) {
            cin >> x >> a;
            cz_3 ( x , a );
        }
        if ( op == 2 ) {
            cin >> x >> y;
            cz_1 ( x , y );
        }
        if ( op == 3 ) {
            cin >> x ;
            cout << cz_2 ( x ) << endl;
            // cout << "/-------------------分割线--------------------/" << endl;
        }
    }
    return 0 ;
}

标签:P3178,cz,int,mid,dfs,HAOI2015,mson,vt,树上
From: https://www.cnblogs.com/dadidididi/p/16839117.html

相关文章

  • 【HNOI_AHOI2018】排列(树上一类全序问题)
    这个条件给的有点诡异:对于任意的\(a_{p_j}=p_k\),都有\(k<j\)。那么对于某个\(a_x=y\),意思就是\(y\)在\(p\)中的位置小于\(x\)在\(p\)中的位置。那么如果我们......
  • 【HDU6326】Monster Hunter(树上一类全序问题)
    先考虑没有树的限制,即我们可以任意安排顺序打怪兽,那么这就是一个全序问题。考虑在某种顺序下,假设初始血量为\(st\),那么打到第\(i\)个怪物时剩余的血量就是\(st+\sum\l......
  • 【AGC023F】01 on Tree(树上一类全序问题)
    显然如果没有树的限制,我们优先选\(0\),然后选\(1\)。如果有了树的限制,我们考虑下面这么一种贪心方法:假设当前能够选的点的集合为\(S\)(初始时\(S\)只包含根),然后选出\(......
  • LOJ #6208. 树上询问
    题目链接:​​传送门​​线段树维护每个点的k,t,d当做懒标记来维护这就需要对懒标记的理解了#include<bits/stdc++.h>#defineusingnamespacestd;typedeflonglongll;......
  • BZOJ 4036([HAOI2015]按位或-子集和变换)
    Description刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal的or)操作。选择数字i的概率是p[i]。保证0<=p[i]<=1,Σp[i]=......
  • P8201 生活在树上(hard version)
    这是一篇大量利用STL的题解。1、题意转化原题说了非常多的路径费用定义,不妨直接画图来研究一下:手摸一下可以发现,对于上图中\(t_1\)、\(t_2\)、\(t_3\)、\(t_4\)四个......
  • accoders NOI #5014. 树上询问(query) 题解
    昨天刚刚做过一道类似的题,没想到在模拟赛当中出现了。题目描述有一棵\(n\)个结点的树,有\(m\)次询问,每次询问给你两个整数\(l,r\),问存在多少个整数\(k\)使得从\(l......
  • ARC150D - Removing Gacha (树上期望)
    Link题意:给一棵\(n\)个节点的树,称一个点是好的,当且仅当它到根的路径上都是黑色(包括自己)。每次在不好的节点中随机选一个把它涂成黑色(不管原来它是否是白的),直到所有点都......
  • Gym - 101147J Whistle's New Car 树上差分
    J.Whistle'sNewCartimelimitpertestmemorylimitpertestinputoutputWhistlehasboughtanewcar,whichhasaninfinitefueltankcapacity.Hediscoveredani......
  • 做题记录整理图论/基环树/树上dp P1453 城市环路(2022/10/19)
    P1453城市环路本质上其实就是一个基环树上的没有上司的舞会但是由于太蒻了第一次接触。。。还是看了题解https://www.luogu.com.cn/blog/Zctoylm/solution-p1453#inc......