Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize ("Ofast,unroll-loops")
- #pragma GCC target ("sse,sse2,sse3,ssse3,sse4")
- #pragma GCC target ("popcnt,abm,mmx,avx,tune=native")
- #include <bits/stdc++.h>
- using namespace std;
- #define sz(x) int(x.size())
- #define pb push_back
- #define FER(i,a,b) for(int i = ll(a); i < ll(b); ++i)
- #define IFR(i,a,b) for(int i = ll(a); i >= ll(b); --i)
- #define all(v) (v).begin(),(v).end()
- #define mp make_pair
- #define ff first
- #define ss second
- #define tm1 first
- #define tm2 second.first
- #define tm3 second.second
- #define fill(x,v) memset(x,v,sizeof(x))
- #define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
- #define sqr(x) (x)*(x)
- #define bas 987625403
- #define N 100010
- typedef long double ld;
- typedef long long ll;
- typedef pair<ll,ll> ii;
- typedef pair<ll,ii> tri;
- typedef vector<ll> vi;
- typedef vector<ii> vii;
- #define trace(...) fff(#__VA_ARGS__,__VA_ARGS__)
- const int oo = 1e9;
- template<typename t> void fff(const char *x, t&& val1){
- cout << x << " : " << val1 << endl;
- }
- template<typename t1, typename... t2> void fff(const char *x, t1&& val1, t2&&... val2){
- const char *xd = strchr(x+1,',');
- cout.write(x,xd-x)<< " : " << val1 << " | ";
- fff(xd+1,val2...);
- }
- const int MAXCD = 1e5 + 5;
- struct CentroidD{
- int n;
- set< int > graph[MAXCD];
- vector<int> cdGraph[MAXCD];
- int sub[MAXCD];
- int cpar[MAXCD];
- int root;
- void add_edge(int a, int b){
- graph[a].insert(b);
- graph[b].insert(a);
- }
- void dfs(int cur, int parent){
- sub[cur] = 1;
- for(int to: graph[cur]){
- if(to != parent && cpar[to] == -1){
- dfs(to, cur);
- sub[cur] += sub[to];
- }
- }
- }
- void decompose(int cur, int parent, int sb, int prevc){
- for(int to: graph[cur]){
- if(to != parent && cpar[to] == -1 && (2 * sub[to] > sb)){
- decompose(to, cur, sb, prevc);
- return;
- }
- }
- cpar[cur] = prevc;
- for(int to: graph[cur]){
- if(cpar[to] == -1){
- dfs(to, - 1);
- decompose(to, cur, sub[to], cur);
- }
- }
- }
- void init(int start){
- for(int i = 0; i < n; ++i) cpar[i] = -1, sub[i] = 0;
- dfs(start, - 1);
- decompose(start, -1, sub[start], -2);
- for(int i = 0; i < n; i ++) if(cpar[i] == -2){
- root = i; break;
- }
- for(int i = 0; i < n; i ++){
- if(cpar[i] == -2) continue;
- cdGraph[i].pb(cpar[i]); cdGraph[cpar[i]].pb(i);
- }
- }
- }cd;
- struct FenwickTree{
- vector<int> ft;
- int LSO(int b){ return (b & (-b) ); }
- FenwickTree(){}
- int rsq(int b){
- int sum = 0; for(;b ; b-= LSO(b)) sum+= ft[b];
- return sum; }
- int rsq(int a, int b){
- return rsq(b) - (a == 1? 0 : rsq(a-1)); }
- //adjusts value of the k-th element by v
- void adjust(int k, int v){
- for(; k < (int)ft.size(); k += LSO(k)) ft[k] += v;
- }
- }fenw;
- queue<int> toAdd, aux, total;
- int A, B;
- ll query(int d){
- int l = A - d + 1, r = B - d + 1;
- if(r <= 0) return 0;
- l = max(l, 1);
- return fenw.rsq(l, r);
- }
- ll add(){
- ll res = 0;
- while(!toAdd.empty()){
- aux.push(toAdd.front());
- res += query(toAdd.front());
- toAdd.pop();
- }
- while(!aux.empty()){
- fenw.adjust(aux.front() + 1, 1);
- total.push(aux.front() + 1);
- aux.pop();
- }
- return res;
- }
- void subtree(int u, int par, int dist){
- toAdd.push(dist);
- for(int v: cd.graph[u]){
- if(v == par) continue;
- subtree(v, u, dist + 1);
- }
- }
- ll compute(ll centroid){
- ll ans = 0;
- fenw.adjust(1, 1); //for centroid root
- for(int v: cd.graph[centroid]){
- subtree(v, centroid, 1);
- ll ret = add();
- ans += ret;
- }
- fenw.adjust(1, -1);
- while(!total.empty()){
- fenw.adjust(total.front(), -1);
- total.pop();
- }
- return ans;
- }
- int main(){
- fastio;
- freopen("awesome.in", "r", stdin);
- int t; cin >> t;
- while(t --){
- int n, l, r; cin >> n >> l >> r;
- cd.n = n;
- FER(i, 0, n) {
- cd.graph[i].clear();
- cd.cdGraph[i].clear();
- }
- A = n - r - 1;
- B = n - l - 1;
- fenw.ft.assign(n + 1, 0);
- FER(i, 0, n - 1){
- int a, b; cin >> a >> b;
- a --; b --;
- cd.add_edge(a, b);
- }
- cd.init(0);
- queue<int> q; q.push(cd.root);
- ll ans = 0;
- while(!q.empty()){
- int u = q.front(); q.pop();
- ans += compute(u);
- for(int v: cd.cdGraph[u]){
- if(v == cd.cpar[u]) continue;
- q.push(v);
- }
- for(int v: cd.graph[u]){
- cd.graph[v].erase(u);
- }
- cd.graph[u].clear();
- }
- //if(r == n - 1) ans += n;
- cout << ans << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement