CF1060E Sergey and Subway 思维

分两种情况讨论

一种为奇数长为$L$的路径,在经过变化后,我们需要走$frac{L}{2} + 1$步

一种为偶数长为$L$的路径,在变化后,我们需要走$frac{L}{2}$步

那么,我们只需要讨论出所有奇数长的路径的个数,再加上原本的路径和,除以2就是答案了

对于奇数长的路径的个数,一定是从奇点走到偶点

对于路径和,考虑每条边的经过次数即可

#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
    #define ri register int
    #define ll long long
    #define tpr template <typename ra>
    #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
    #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    int wr[50], rw;
    #define pc(iw) putchar(iw)
    tpr inline void write(ra o, char c = '
') {
        if(!o) pc('0');
        if(o < 0) o = -o, pc('-');
        while(o) wr[++ rw] = o % 10, o /= 10;
        while(rw) pc(wr[rw --] + '0');
        pc(c);
    }
}
using namespace std;
using namespace remoon;

#define sid 500050

ll ans;
int n, cnp, num[2];
int sz[sid], cap[sid], nxt[sid], node[sid];

inline void addedge(int u, int v) {
    nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
}

#define cur node[i]
inline void dfs(int o, int fa, int dep = 0) {
    sz[o] = 1; num[dep] ++;
    for(int i = cap[o]; i; i = nxt[i]) 
    if(cur != fa) {
        dfs(cur, o, dep ^ 1);
        sz[o] += sz[cur];
    }
    ans += 1ll * sz[o] * (n - sz[o]);
}

int main() {
    n = read();
    rep(i, 2, n) {
        int u = read(), v = read();
        addedge(u, v); addedge(v, u);
    }
    dfs(1, 0);
    ans += 1ll * num[0] * num[1];
    write(ans >> 1);
    return 0;
}
原文地址:https://www.cnblogs.com/reverymoon/p/9825019.html