求条悬棺
查看原帖
求条悬棺
741580
niuqichongtian楼主2024/11/22 21:34
#include <bits/stdc++.h>
#define I using
#define AK namespace
#define IOI std;
#define int long long
#undef INT_MIN
#define INT_MIN (LONG_LONG_MIN + 1145)
#undef INT_MAX
#define INT_MAX (LONG_LONG_MAX - 1145)
#define P1 "标记点1"
#define P2 "标记点2"
#define P3 "标记点3"
#define P4 "标记点4"
#define P5 "标记点5"
#define P6 "标记点6"
#define P7 "标记点7"
#define P8 "标记点8"
#define P9 "标记点9"
#define P0 "标记点0"
I AK IOI;

namespace CSP {
    inline void read ( int &x ) {
        x = 0;
        char c = getchar();
        int pn = 1;
        while ( !isdigit ( c ) ) {
            if ( c == '-' ) {
                pn = -1;
            }
            c = getchar();
        }
        while ( isdigit ( c ) ) {
            x = x * 10 + c - 48;
            c = getchar();
        }
        x *= pn;
        return;
    }
    inline void write ( int x ) {
        if ( x < 0 ) {
            putchar ( '-' ), x = -x;
        }
        if ( x >= 10 ) {
            write ( x / 10 );
        }
        putchar ( x % 10 + 48 );
        return;
    }
    struct inputstream {
        inputstream operator>> ( int &x ) {
            read ( x );
            return *this;
        }
    } in;
    struct outputstream {
        outputstream operator<< ( int x ) {
            write ( x );
            putchar ( 10 );
            return *this;
        }
    } out;
}
I AK CSP;

int N, Q;
int w[100007];
vector<int> e[100007];
int st_sum[20][100007];                                 // 代表从st_plc[i][j]向前,不包括j的区间权值和
int st_plc[20][100007];                                 // 代表j的2^i父节点
int d[100007];                                          // 这个节点的深度(以1为根)
bool vis[100007];                                       // dfs会用到

inline void dfs ( int u, int dep ) {
    d[u] = dep;
//    cout << "d[" << u << "] equals " << d[u];
    for ( int v : e[u] ) {
        if ( !vis[v] ) {
            vis[v] = 1;
            dfs ( v, dep + 1 );
//            vis[v] = 0;
        } else {
            st_plc[0][u] = v;
            st_sum[0][u] = w[v];
        }
    }
}

inline void build ( void ) {
    vis[1] = 1;
    dfs ( 1, 0 );
    for ( int i = 1, k = 2; k <= N; i++, k <<= 1 ) {
        for ( int j = 1; j <= N; j++ ) {
            st_plc[i][j] = st_plc[i - 1][st_plc[i - 1][j]];
            st_sum[i][j] = st_sum[i - 1][j] + st_sum[i - 1][st_plc[i - 1][j]];
        }
    }
    return;
}

inline int query ( int u, int v ) {
    int ans = w[u] + w[v];
    if ( d[u] < d[v] ) {
        swap ( u, v );
    }
    for ( int p = 19; p >= 0; p-- ) {
        if ( d[st_plc[p][u]] >= d[v] ) {
            ans += st_sum[p][u];
            u = st_plc[p][u];
//            out << d[u];
        }
    }
    if ( u == v ) {
        return ans - w[u];
    }
    for ( int p = 19; p >= 0; p-- ) {
        if ( st_plc[p][u] != st_plc[p][v] ) {
            ans += st_sum[p][u];
            ans += st_sum[p][v];
            u = st_plc[p][u], v = st_plc[p][v];
        }
    }
//    out << u << v;
    return ( ans + st_sum[0][u] );
}

signed main ( signed argc, char const *argv[] ) {
    int u, v;
    in >> N >> Q;
    for ( int i = 1; i < N; i++ ) {
        in >> u >> v;
        e[u].push_back ( v );
        e[v].push_back ( u );
    }
    for ( int i = 1; i <= N; i++ ) {
        w[i] = e[i].size();
//        out << d[i];
//        out << w[i];
    }
    build();
    while ( Q-- ) {
        in >> u >> v;
        out << query ( u, v );
    }
    return 0;
}

my record

可能是有关ST表的问题,请大佬指教(╹▽╹)

2024/11/22 21:34
加载中...