hdu 5044 树链剖分+前缀和

来源:互联网 发布:万达电商 淘宝卖货 编辑:程序博客网 时间:2024/05/19 22:52
树链剖分裸题,主要是区间修改,最后一次查询,用前缀和来获取,复杂度o(1),时间卡得太死........#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cctype>#define MAX 100007using namespace std;typedef long long LL;void scan_num ( int &x ){    char c = getchar ( );    x = 0;    while ( !isdigit( c ) ) c = getchar ();    while ( isdigit(c) )         x = x*10 + c - 48,        c = getchar ( );}void scan_str ( char s[] ){    char c = getchar ();    int i = 0;    while ( !isalnum( c ) ) c = getchar ();    while ( isalnum ( c ) )         s[i++] = c,        c = getchar ();    s[i] = 0;}struct Edge{    int v , next , id;}e[MAX<<1];int head[MAX];int cc,tim;void add ( int u , int v , int id ){    e[cc].v = v;    e[cc].id = id;    e[cc].next = head[u];    head[u] = cc++;}int dep[MAX],siz[MAX],son[MAX],tid[MAX],fid[MAX],fa[MAX],top[MAX],loc[MAX];void dfs ( int u , int p , int d ){    son[u] = -1;    fa[u] = p;    siz[u] = 1;    dep[u] = d;    for ( int i = head[u]; ~i; i = e[i].next )    {        int v = e[i].v;        if ( v == p ) continue;        loc[v] = e[i].id;        dfs ( v , u , d+1 );        siz[u] += siz[v];        if ( son[u] == -1 || siz[son[u]] < siz[v] )            son[u] = v;    }}void dfs ( int u , int tp ){    top[u] = tp;    tid[u] = ++tim;    fid[tid[u]] = u;    if ( son[u] == -1 ) return;    dfs ( son[u] , tp );    for ( int i = head[u]; ~i; i = e[i].next )    {        int v = e[i].v;        if ( v == son[u] || v == fa[u] ) continue;        dfs ( v , v );    }}   LL p[2][MAX<<1];void change ( int x , int y , int v , int f ){    while ( top[x] != top[y] )    {        if ( dep[top[x]] < dep[top[y]] ) swap ( x , y );        if ( f )             p[1][tid[top[x]]*2-1] += v,            p[1][tid[x]*2] -= v;        else             p[0][tid[top[x]]] += v,            p[0][tid[x]+1] -= v;        x = fa[top[x]];    }    if ( dep[x] > dep[y] ) swap ( x , y );    if ( f )        p[1][tid[x]*2] += v,        p[1][tid[y]*2] -= v;    else         p[0][tid[x]] += v,        p[0][tid[y]+1] -= v;}int t,n,m,u,v,k;char s[15];LL ans0[MAX],ans1[MAX];int main ( ){    int c = 1;    scan_num ( t );    while ( t-- )    {        scan_num ( n );        scan_num ( m );        memset ( head , -1 , sizeof ( head ) );        memset ( p , 0 , sizeof ( p ) );        tim = cc = 0;        for ( int i = 1 ; i < n ; i++ )        {            scan_num ( u );            scan_num ( v );            add ( u , v , i );            add ( v , u , i );         }        dfs ( 1 , -1 , 0 );        dfs ( 1 , 1 );        for ( int i = 0 ; i < m ; i++ )        {            //scan_str ( s );            scanf ( "%s" , s );            scan_num ( u );            scan_num ( v );            scan_num ( k );            if ( s[3] == '1' )                change ( u , v , k , 0 );            else                 change ( u , v , k , 1 );        }        p[0][0] = p[1][0] = 0;       /* cout << "_________________________" << endl;        for ( int i = 1 ; i <= 2*n ; i++ )        {            cout << p[1][i] << " ";        }        cout << endl;        cout << "_________________________" << endl;*/        for ( int i = 1 ; i <= n ; i++ )            p[0][i] += p[0][i-1];        for ( int i = 1 ; i <= n*2 ; i++ )            p[1][i] += p[1][i-1];        /*cout << "___________________________" << endl;        for ( int i = 1 ; i <= 2*n ; i++ )        {            cout << p[1][i] << " ";        }        cout << endl;        cout << "____________________________" << endl;*/        /*for ( int i = 2 ; i <= n ; i++ )        {            cout << loc[fid[i]] << " ";        }        cout << endl;        cout << "_____________________________" << endl;*/        for ( int i = 1 ; i <= n ; i++ )            ans0[fid[i]] = p[0][i];        for ( int i = 2 ; i <= n ; i++ )            ans1[loc[fid[i]]] = p[1][2*i-1];        printf ( "Case #%d:\n" , c++ );        for ( int i = 1 ; i <= n ; i++ )        {            if ( i != 1 ) printf ( " " );            printf ( "%I64d" , ans0[i] );        }        puts ("");        for ( int i = 1 ; i < n ; i++ )        {            if ( i != 1 ) printf ( " " );            printf ( "%I64d" , ans1[i] );        }        puts ("");         }    return 0;}

0 0