// compile: make data
// run: time ./data < big.in
#include <bits/stdc++.h>
using namespace std;
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP std::cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define MAXN 200010
struct tree {
int n;
vector<vector<int>> e;
struct node {
vector<node*> ch;
node *parent = nullptr;
int size, depth, height;
};
vector<node> vertex;
vector<int> removed;
node *root;
tree(int V) {
n = V;
e.resize(n);
vertex.resize(n);
removed.assign(n, 0);
}
void add_edge(int u, int v) {
e[u].push_back(v), e[v].push_back(u);
}
int ind(node *x) {return x - &vertex[0]; }
void setroot(int rt = 0) {
if (root != &vertex[rt]) build(rt);
root = &vertex[rt];
}
void build(int rt) {
function<void(int, int)> dfs = [&](int u, int pre) {
node *x = &vertex[u];
x->size = 1;
x->depth = !~pre ? 0 : x->parent->depth + 1;
x->height = 1;
x->ch.clear();
for (int v: e[u]) {
if (v == pre || removed[v]) continue;
node *y = &vertex[v];
x->ch.push_back(y);
y->parent = x;
dfs(v, u);
x->size += y->size;
cmax(x->height, y->height + 1);
}
};
dfs(rt, -1);
}
int centroid(int r = -1) {
if (~r) build(r);
else r = ind(root);
int N = vertex[r].size;
if (N <= 2) return r;
for (node *x = &vertex[r]; x; ) {
int maxsz = -INF;
node *maxnode = nullptr;
for (auto y: x->ch) if (y->size > maxsz) maxsz = y->size, maxnode = y;
if (maxsz <= N / 2) return ind(x);
x = maxnode;
}
return r;
}
void centroid_decomp(auto solve) {
auto getvs = [&](int u) -> vector<int> {
vector<int> vs;
queue<int> q; q.push(u);
while (!q.empty()) {
int x = q.front(); q.pop();
vs.push_back(x);
for (auto y: vertex[x].ch) q.push(ind(y));
}
return vs;
};
function<void(node*)> dfs = [&](node *x) -> void {
int c = centroid(ind(x));
if(c != ind(x)) build(c);
vector<vector<int>> vs;
for (auto y: vertex[c].ch) vs.push_back(getvs(ind(y)));
solve(c, vs);
removed[c] = 1, vertex[c].ch.clear();
for (auto v: e[c]) if (!removed[v]) dfs(&vertex[v]);
};
dfs(root);
}
// void graphviz_dump(int plus = 0, string filename = "graph.dot") {
// string vlabel = "", elabel = "";
// // vlabel = " color=\"red\"";
// // elabel = " color=\"red\"";
// set<int> vset; set<pair<int, int>> eset;
// rep(i, 0, n) if (vertex[i].heavy) vset.insert(ind(vertex[i].heavy)), eset.insert({i, ind(vertex[i].heavy)});
// FILE *f = fopen(filename.c_str(), "w");
// fprintf(f, "digraph Tree {\n");
// rep(i, 0, n) {
// node *x = &vertex[i];
// fprintf(f, " %lld;\n", vset.count(i) ? vlabel.c_str() : "");
// }
// rep(i, 0, n) {
// node *x = &vertex[i];
// for (auto y: x->ch) {
// fprintf(f, " %ld -> %ld[arrowhead=\"none\"%s];\n", x - &vertex[0], y - &vertex[0], eset.count({i, ind(y)}) ? elabel.c_str() : "");
// }
// }
// fprintf(f, "}\n");
// }
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, k; cin >> n >> k;
tree g(n);
rep(i, 0, n-1) {
int u, v; cin >> u >> v; --u, --v;
g.add_edge(u, v);
}
g.setroot(0);
int answer = 0;
auto solve = [&](int root, vector<vector<int>>& subtrees) -> void {
auto getans = [](vector<int> &hs, int k) -> int {
int ans = 0;
for (int i = 0; i < sz(hs) && k-i>=i; ++i) {
if (k-i < 0 || k-i >= sz(hs)) continue;
ans += i==k-i ? (hs[i] * (hs[k-i]-1))/2 : hs[i] * hs[k-i];
}
return ans;
};
vector<int> cnt = {1};
int minus = 0;
for (auto &vs: subtrees) {
vector<int> cur;
for (auto i: vs) {
int d = g.vertex[i].depth;
if (d >= sz(cur)) cur.resize(d+1);
++cur[d];
}
minus += getans(cur, k);
if (sz(cur) > sz(cnt)) cnt.resize(sz(cur));
rep(i, 0, sz(cur)) cnt[i] += cur[i];
}
answer += getans(cnt, k) - minus;
};
g.centroid_decomp(solve, k);
cout << answer << endl;
return 0;
}
188betlinkvao.org is another alternative to connect to 188bet. Used it yesterday without issue. Click the link 188betlinkvao.
Yo, anyone else tried gamebetvina? The user interface looks clean. Wondering if anyone’s hit a big win there. Share your experiences with gamebetvina!
How’s it hanging? Been messing with 888pbet. It’s okay, nothing groundbreaking, but it gets the job done. Worth a gander if you’re just browsing. Give 888pbet a try.