8.4 POJ 3237 (split tree chain segment tree +

Meaning of the title: the right side of the split tree chain, three operations

1.CHANGE of the weights of edges to a i

2.NEGATE the first point to a second point b of edge weights, all take the inverse number

3.QUERY find a point of maximum side to the right of the point b.

 

analysis:

The child is not Kanban own silent chain tree split ha ha

Not surprisingly error occurred:

1. Front chain unfamiliar with the star, before all vector deposit side, but the chain tree split on the question poj like vectoc time out

2. negated lazy update mark to be considered negatives make a positive

 

This complicated the tree line with struct memory to write more clearly, better than some of the array

//树链剖分 b
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

#define fi first
#define se second
#define rep( i ,x ,y ) for( int i= x; i<= y ;i++ )
#define reb( i ,y ,x ) for( int i= y; i>= x ;i-- )
#define mem( a ,x ) memset( a ,x ,sizeof(a))
#define li i<<1
#define ri i<<1|1
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int ,int> pii;
typedef pair<ll ,ll> pll;
typedef pair<string ,int> psi;

const int inf = 0x3f3f3f3f;
const int N = 100005;
const int M = 1000005;

struct Tree{
    int i ,l ,r;
    int mn ,mx ,lazy;
} tr[N<<2];

struct E{
    int u ,v ,c;
}e[N];

struct Edge{
    int to ,next;
}edge[N<<1];

int val[N] ,head[N<<1];
int fa[N] ,son[N] ,sz[N] ,top[N] ,dfn[N] ,rnk[N] ,dep[N];
int n ,q ,tot=0 ,cnt = 0; 

// segment tree


inline void addedge(int u ,int v){
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
    //cout<<u<<" "<<v<<" cnt "<<cnt<<endl;
}

inline void neg( int i ){
    tr[i].mx *=-1; tr[i].mn *=-1;
    swap( tr[i].mx ,tr[i].mn);
}

inline void push_up( int i ){
    tr[i].mx = max( tr[li].mx ,tr[ri].mx );
    tr[i].mn = min( tr[li].mn ,tr[ri].mn );
}

inline void push_down( int i ){
    if( !tr[i].lazy )return;    
    tr[i].lazy = 0;
    // lazy取反 负负得正 
    tr[li].lazy ^= 1 ; tr[ ri].lazy ^= 1;
    
    neg(li); neg(ri);
    return;
}

void build( int i ,int L ,int R ){
    tr[i].l = L; tr[i].r = R;
    tr[i].lazy = 0;
    if( L== R ){
        tr[i].mn = tr[i].mx = val[ rnk[L] ];
        return;
    }
    int m = (tr[i].l+tr[i].r)>>1;
    build( li ,L ,m );
    build( ri ,m+1 ,R);
    push_up( i );
}

void negat( int i ,int L ,int R){
    if( tr[i].l == tr[i].r ){
        neg( i );
        return;
    }
    push_down(i);
    
    if( L <= tr[i].l && tr[i].r <= R ){
        tr[i].lazy = 1;
        neg( i );
        return;
    }
    
    int m = (tr[i].l+tr[i].r)>>1;
    if( L <= m )negat( li ,L ,R );
    if( R >  m )negat( ri ,L ,R );
    
    push_up(i);
    return;
}

void updata( int i ,int p ,int k ){
    
    if( tr[i].l ==p && tr[i].r==p ){
        tr[i].mn = tr[i].mx = k;
        return;
    }
    
    push_down(i);
    
    int m = (tr[i].l+tr[i].r)>>1;
    if( p <= m )updata( li ,p ,k );
    if( p >  m )updata( ri ,p ,k );
    
    push_up(i);
    return;
    
}

int query(int i ,int L, int R ){
    //cout<<"q l ,r "<<tr[i].l<<" "<<tr[i].r<<" L ,R "<<L << " " <<R <<" " <<rnk[L] <<" "<<rnk[R]<<endl; 
    if( tr[i].l == tr[i].r ){
        return tr[i].mx;
    }
    push_down(i);
    
    int mx = -inf;
    if( L <= tr[i].l && tr[i].r <= R ){
        return tr[i].mx;
    }
    
    int m = (tr[i].l+tr[i].r)>>1;
    if( L <= m )mx =max( mx ,query(li ,L ,R ) );
    if( R >  m )mx =max( mx ,query(ri ,L ,R ) );

    return mx;
}
// c_tree
void init( ){
    tot = cnt = 0;
    mem( head ,0 );
    mem( son ,0 );
}

void dfs1( int u ,int f ,int d ){
    sz[u] = 1;
    fa[u] = f;
    dep[u] = d;
    
    for( int i= head[u] ; i ;i = edge[i].next ){
        int v = edge[i] .to;
        if( v==f )continue;
        dfs1( v ,u ,d+1 );
        sz[u] += sz[v];
        if( sz[ son[u] ] < sz[v] )son[u] = v;
    }
}

void dfs2( int u ,int tp ){
    top[u] = tp;
    dfn[u] = ++ tot;
    rnk[tot] = u;
    
    if( son[u] )dfs2( son[u] ,tp );
    for( int i =head[u] ;i ;i = edge[i].next ){
        int v = edge[i].to;
        if( v!= fa[u] && v!=son[u] )dfs2(v ,v);    
    }
}

void c_negate( int x ,int y ){
    int fx = top[x] ,fy = top[y];
    while( fx!=fy ){
        if( dep[fx] < dep[fy] ){
            swap( x ,y ); swap(fx ,fy);
        }
        negat( 1 ,dfn[fx] ,dfn[x] );
        x= fa[fx]; fx = top[x];
    }
    
    if( x==y )return;
    if( dfn[x] > dfn[y] )swap(x ,y);
    negat( 1 ,dfn[son[x]] ,dfn[y] );
}


int c_query(int x ,int y ){
    int mx = -inf;
    int fx = top[x] ,fy = top[y];
    //cout<<x<< " " <<y<<" " <<fx <<" "<<fy<<endl;
    while( fx!=fy ){
        if( dep[fx] < dep[fy] ){
            swap( x ,y ); swap(fx ,fy);
        }
        mx = max(mx ,query( 1 ,dfn[fx] ,dfn[x] ) );
        x= fa[fx]; fx = top[x];
    }

    if( x==y )return mx;
    if( dfn[x] > dfn[y] )swap(x ,y);
    mx = max(mx ,query( 1 ,dfn[son[x]] ,dfn[y] ) );
    return mx;
}

void rev_val( ){
    rep( i ,1 ,n-1 ){
        int u =e[i].u ,v = e[i].v;
        if( dep[v] > dep[u] )swap( e[i].u ,e[i].v );
        val[ e[i].u ] = e[i].c;
    }
}

int T;
int main( ){
    //freopen( "out.txt" ,"w" ,stdout );
    scanf( "%d" ,&T );
    while( T-- ){
        init( );
        
        scanf("%d" ,&n);
        rep( i ,1 ,n-1 ){
            scanf("%d%d%d" ,&e[i].u ,&e[i].v ,&e[i].c);
            addedge( e[i].u ,e[i].v );
            addedge( e[i].v ,e[i].u );
            
        }
        
        dfs1( 1 ,0 ,1 );
        dfs2( 1 ,1 );
        rev_val( );
        
        build( 1 ,1 ,n );
        
        char op[15] ;
        int a ,b ,v;
        while( true ){
            cin >>op;
            if(op[0]=='D')break;
            if(op[0]=='C'){
                scanf("%d%d" ,&a ,&v );
                updata( 1 ,dfn[ e[a].u ] ,v );
            }
            if( op[0]=='Q' ){
                scanf("%d%d" ,&a ,&b );
                printf("%d\n" ,c_query(a ,b));
            }
            if( op[0]=='N' ){
                scanf("%d%d" ,&a ,&b );
                c_negate( a, b );
            } 
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/-ifrush/p/11299507.html