牛半仙的妹子Tree(Nowcoder)

   日期:2020-11-04     浏览:96    评论:0    
核心提示:题目牛半仙的妹子的座位呈一个树状结构,由 n 个点和 n−1 条边组成,1 号结点为根。 当牛半仙的一个妹子无视 牛半仙后,一个单位时间后周围的妹子也会无视牛半仙。 有些时候牛半仙为了吸引妹子们的注意,会开启鬼畜模式,这时所有妹子无视牛半仙的状态都会消失, 恢复正常,并且这之后的状态不会被之前影响。 牛半仙想知道某个妹子是否无视了他,于是他找到了你,请你帮帮他‘题解&思路自己的思路:感觉这还是一道较为简单的树剖题...(TM调了一天)当询问的x满足

题目

牛半仙的妹子的座位呈一个树状结构,由 n 个点和 n−1 条边组成, 1 号结点为根。 当牛半仙的一个妹子无视 牛半仙后,一个单位时间后周围的妹子也会无视牛半仙。 有些时候牛半仙为了吸引妹子们的注意,会开启鬼畜模式,这时所有妹子无视牛半仙的状态都会消失, 恢复正常,并且这之后的状态不会被之前影响。 牛半仙想知道某个妹子是否无视了他,于是他找到了你,请你帮帮他

题解&思路

自己的思路:

感觉这还是一道较为简单的树剖题...(TM调了一天)

当询问的x满足

v是操作后最初的无视节点,now是当前时刻

然后转化一下即可:

把每一个v放在lca上,这样就是链修改链查询了,然后直接上树剖即可

可是为什么这道题调了一天呢??还是一个细节问题::

void change( int x , int u ){
    int t = dep[x] + u;
    if( top[x] != 1 ){
        modify( 1 , id[top[x]] , id[x] ,t );
        x = fa[top[x]];
    }
    modify( 1 , 1 , id[x] ,t );
}

TM把树剖的修改写成这样了。。。。while写成了if

细节部分一定要引以为戒,在用眼查的时候最好就先查出来!!!

代码

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int MAXN = 1e5 + 3;
int n , m , head[MAXN] , cnt = 1;
int dep[MAXN] , dfn[MAXN] , zson[MAXN] , top[MAXN] ,fa[MAXN] , inde , id[MAXN] , siz[MAXN];
struct edge{
    int to , nex ;
}G[MAXN<<1];
void add_edge( int x, int y ){
    G[cnt].nex = head[x] , G[cnt].to = y;
    head[x] = cnt ++;
}
void dfs( int x , int f ){
    siz[x] = 1;
    for( int i = head[x] ; i ; i =G[i].nex ){
        int v = G[i].to;
        if( v == f ) continue;
        dep[v] = dep[x] + 1;
        fa[v] = x;
        dfs( v , x );
        siz[x] += siz[v];
        if( !zson[x] || siz[zson[x]] < siz[v] ) zson[x] = v;
    }
}
void dfs1( int x, int f ){
    top[x] = f;
    dfn[++inde] = x;id[x] = inde;
    if( !zson[x] ) return ;
    dfs1( zson[x] , f );
    for( int i = head[x] ; i ; i = G[i].nex ){
        int v =G[i].to;
        if( v == fa[x] || v == zson[x] ) continue;
        dfs1( v , v );
    }
}
struct tree{
    int l , r , lazy , minn , lazy1;
}tre[MAXN<<2];
void build( int i , int l , int r ){
    tre[i].l = l , tre[i].r = r , tre[i].lazy = tre[i].lazy1 = 0 , tre[i].minn = inf;
    if( l == r ) return ;
    int mid = l + r >> 1;
    build( i << 1 , l , mid );
    build( i << 1 | 1,  mid + 1, r );
}
void pushdown( int i ){
    if( tre[i].lazy1 ){
        tre[i<<1].minn = tre[i<<1|1].minn = inf , tre[i<<1].lazy1 = tre[i<<1|1].lazy1 = inf;
        tre[i<<1].lazy = tre[i<<1|1].lazy = 0;
        tre[i].lazy1 = 0 ;
    }
    if( tre[i].lazy ){
    	tre[i<<1].minn = min( tre[i<<1].minn , tre[i].lazy - 2 * dep[dfn[tre[i<<1].r]] );
    	if( !tre[i<<1].lazy ) tre[i<<1].lazy = tre[i].lazy;
    	else tre[i<<1].lazy = min( tre[i<<1].lazy , tre[i].lazy );
    	tre[i<<1|1].minn = min( tre[i<<1|1].minn , tre[i].lazy - 2 * dep[dfn[tre[i<<1|1].r]] );
    	if( !tre[i<<1|1].lazy ) tre[i<<1|1].lazy = tre[i].lazy;
    	else
            tre[i<<1|1].lazy = min( tre[i<<1|1].lazy , tre[i].lazy );
    	tre[i].lazy = 0;
	}
}
void modify( int i , int l , int r , int delta ){
    if( tre[i].l > r || tre[i].r < l ) return;
    if( tre[i].l >= l && tre[i].r <= r ){
        if( delta != inf ){
            tre[i].minn = min( tre[i].minn , delta - 2 * dep[dfn[tre[i].r]] );
            if( !tre[i].lazy ) tre[i].lazy = delta;
            else tre[i].lazy = min( delta , tre[i].lazy );
        }
        else{
            tre[i].lazy1 = inf , tre[i].minn = inf;//tre[i].lazy = 0;
        }
        return ;
    }
    pushdown( i );
    modify( i << 1 , l , r , delta );
    modify( i << 1 | 1, l , r , delta );
    tre[i].minn = min( tre[i<<1].minn , tre[i<<1|1].minn );
}
int query( int i , int l , int r ){
    if( tre[i].l > r || tre[i].r < l ) return inf;
    if( tre[i].l >= l && tre[i].r <= r ){
        return tre[i].minn;
    }
    pushdown( i );
    int ans = query( i << 1 , l , r );
    ans = min( ans , query( i << 1 | 1 , l , r )) ;
    tre[i].minn = min( tre[i<<1].minn , tre[i<<1|1].minn );
    return ans;
}
void change( int x , int u ){
    int t = dep[x] + u;
    if( top[x] != 1 ){
        modify( 1 , id[top[x]] , id[x] ,t );
        x = fa[top[x]];
    }
    modify( 1 , 1 , id[x] ,t );
}
void get_ans( int x , int u ){
    int t = u - dep[x];
    while( top[x] != 1 ){
        int tot = query( 1 , id[top[x]] , id[x] );
        if( tot <= t ){
            printf( "wrxcsd\n" );
            return ;
        }
        x = fa[top[x]];
    }
    int tot = query( 1 , 1 , id[x] );
    if( tot <= t )
        printf( "wrxcsd\n" );
    else
        printf( "orzFsYo\n" );
}
int main(){
	//freopen( "B.out" , "r" , stdin );
	//freopen( "C.out" , "w" , stdout );
    scanf( "%d%d" , &n , &m );
    dep[1] =1;
    for( int i = 1 ; i < n ; i ++ ){
        int x , y;scanf( "%d%d" , &x , &y );
        add_edge( x , y);
        add_edge( y , x );
    }
    dfs( 1,0 );
    dfs1( 1 , 1 );
    build( 1 , 1 , n );
    int u = 0;
    while( m -- ){
        u ++;
        int op , x;scanf( "%d%d" , &op , &x );
        if( op == 1 ){
            change( x , u );
        }
        else if( op == 2 )
            modify( 1 , 1 , n , inf );
        else{
            get_ans( x , u );
        }
    }
    return 0;
}

 

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服