【HDU】5796 Magic Number【lca】

来源:互联网 发布:手机用数据会出400bad 编辑:程序博客网 时间:2024/05/02 05:02

题目链接:Magic Number

看懂题目,就知道怎么做

#include <stdio.h>#include <vector>#include <string.h>#include <algorithm>using namespace std ;typedef long long LL ;typedef pair < int , int > pii ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 5005 ;const int N = 1000005 ;int n , m , q ;int a[MAXN] , b[MAXN] , c[N] ;int f[MAXN][15] , dep[MAXN] ;int dfn[MAXN] , dfs_time ;vector < int > G[MAXN] ;int lca ( int x , int y ) {    if ( dep[x] < dep[y] ) swap ( x , y ) ;    for ( int i = 14 ; ~i ; -- i ) {        if ( dep[x] - ( 1 << i ) >= dep[y] ) x = f[x][i] ;    }    if ( x == y ) return x ;    for ( int i = 14 ; ~i ; -- i ) {        if ( ~f[x][i] && ~f[y][i] && f[x][i] != f[y][i] ) {            x = f[x][i] ;            y = f[y][i] ;        }    }    return f[x][0] ;}void dfs ( int u ) {    dfn[u] = ++ dfs_time ;    for ( int i = 0 ; i < G[u].size () ; ++ i ) {        dfs ( G[u][i] ) ;    }}int cmp ( const int& a , const int& b ) {    return dfn[a] < dfn[b] ;}void scanf ( int& x , char c = 0 ) {    while ( ( c = getchar () ) < '0' ) ;    x = c - '0' ;    while ( ( c = getchar () ) >= '0' ) x = x * 10 + c - '0' ;}void solve () {    clr ( f , -1 ) ;    dfs_time = 0 ;    scanf ( "%d%d" , &n , &m ) ;    for ( int i = 1 ; i <= n ; ++ i ) {        G[i].clear () ;    }    for ( int i = 1 ; i <= m ; ++ i ) {        scanf ( a[i] ) ;        a[i] ++ ;    }    sort ( a + 1 , a + m + 1 ) ;    int j = 1 ;    for ( int i = 1 ; i <= n ; ++ i ) {        int x = -1 , l = i * ( i - 1 ) / 2 + 1 , r = i * ( i + 1 ) / 2 ;        while ( j <= m && a[j] <= r ) {            int t = a[j ++] - l + 1 ;            if ( t >= i ) continue ;            if ( x == -1 ) x = t ;            else x = lca ( x , t ) ;        }        if ( x == -1 ) x = 0 ;        dep[i] = dep[x] + 1 ;        f[i][0] = x ;        G[x].push_back ( i ) ;        for ( int j = 1 ; j < 15 ; ++ j ) {            if ( ~f[i][j - 1] ) f[i][j] = f[f[i][j - 1]][j - 1] ;        }    }    dfs ( 0 ) ;    scanf ( "%d%d" , &q , &m ) ;    for ( int i = 1 ; i <= q ; ++ i ) {        scanf ( b[i] ) ;    }    for ( int i = 1 ; i <= m ; ++ i ) {        scanf ( c[i] ) ;        c[i] ++ ;    }    sort ( c + 1 , c + m + 1 ) ;    int tot = 0 ;    j = 1 ;    for ( int i = 1 ; i <= q ; ++ i ) {        int l = tot + 1 , r = tot + b[i] , n1 = 0 ;        while ( j <= m && c[j] <= r ) {            int t = c[j ++] - l + 1 ;            if ( t <= n ) a[n1 ++] = t ;        }        sort ( a , a + n1 , cmp ) ;        int ans = 0 ;        for ( int j = 0 ; j < n1 ; ++ j ) {            ans += dep[a[j]] ;            if ( j ) ans -= dep[lca ( a[j - 1] , a[j] )] ;        }        printf ( "%d\n" , ans ) ;        tot += b[i] ;    }}int main () {    int T ;    scanf ( "%d" , &T ) ;    for ( int i = 1 ; i <= T ; ++ i ) {        printf ( "Case #%d:\n" , i ) ;        solve () ;    }    return 0 ;}
0 0
原创粉丝点击