Submission #1242092

#TimeUsernameProblemLanguageResultExecution timeMemory
1242092altern23Shymbulak (IZhO14_shymbulak)C++20
0 / 100
28 ms11332 KiB
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define pii pair<ll, ll>
#define fi first
#define sec second
#define ld long double

const int MAXN = 2e5;
const ll INF = 1e18;
const int MOD = 998244353;
const ld eps = 1e-6;	

ll vis[MAXN + 5], cycle[MAXN + 5];

vector<ll> adj[MAXN + 5];
ll p[MAXN + 5], st, en;
ll d[MAXN + 5];
map<ll, ll> freq;

void dfs2(ll idx, ll par){
	vis[idx] = 1;
	freq[d[idx]]++;
	for(auto i : adj[idx]){
		if(!vis[i] && !cycle[i]){
			d[i] = d[idx] + 1;
			dfs2(i, idx);
		}
	}
}

void dfs(ll idx, ll par){
	vis[idx] = 1;
	for(auto i : adj[idx]){
		if(i == par) continue;
		if(vis[i]) st = i, en = idx;
		else{
			p[i] = idx;
			dfs(i, idx);
		}
	}
}

struct node{
	ll MX, cnt;
};

struct ST{
	ll N;
	vector<node> sg;
	ST(ll _n){
		N = _n;
		sg.resize(4 * N + 5);
		for(int i = 0; i <= 4 * N; i++) sg[i] = {-INF, 0};
	}
	node comb(node a, node b){
		node c;
		if(a.MX == b.MX) c = {a.MX, a.cnt + b.cnt};
		else if(a.MX > b.MX) c = a;
		else c = b;
		
		return c;
	}
	void upd(ll l, ll r, ll cur, ll idx, node val){
		if(l == r){
			sg[cur] = val;
		}
		else{
			ll mid = (l + r) / 2;
			if(idx <= mid) upd(l, mid, cur * 2, idx, val);
			else upd(mid + 1, r, cur * 2 + 1, idx, val);
			sg[cur] = comb(sg[cur * 2], sg[cur * 2 + 1]);
		}
	}
	node query(ll l, ll r, ll cur, ll x, ll y){
		if(l > y || r < x) return {-INF, 0};
		if(l >= x && r <= y) return sg[cur];
		ll mid = (l + r) / 2;
		return comb(query(l, mid, cur * 2, x, y), query(mid + 1, r, cur * 2 + 1, x, y));
	}
};

int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);		
	int tc = 1;	
	// cin >> tc;
	for(;tc--;){
		ll N; cin >> N;
		for(int i = 1; i <= N; i++){
			ll u, v; cin >> u >> v;
			adj[u].push_back(v), adj[v].push_back(u);
		}
		dfs(1, -1);
		
		ll sz = 1;
		d[st] = 0;
		while(st != en){
			cycle[st] = 1;
			d[p[st]] = d[st] + 1;
			sz++;
			st = p[st];
		}
		cycle[en] = 1;
		
		ST pos(sz), neg(sz);
		for(int i = 1; i <= N; i++) vis[i] = 0;
		
		ll cur = 0, ans = 0;
		for(int tt = 1; tt <= N; tt++){
			if(cycle[tt]){
				freq.clear();
				dfs2(tt, -1);
				vector<pii> v;
				for(auto x : freq) v.push_back(x);
				sort(v.begin(), v.end(), greater<pii>());
				ll cur_mx = v[0].fi, cur_cnt = v[0].sec;
				ll i = d[tt], j = cur_mx - d[tt];
				ll batas = i - sz / 2;
				
				if(v[0].sec == 1){
					if(v.size() > 1){
						if(cur < v[0].fi + v[1].fi - 2 * i){
							ans = v[0].sec * v[1].sec;
							cur = v[0].fi + v[1].fi - 2 * i;
						}
						else if(cur == v[0].fi + v[1].fi - 2 * i){
							ans += v[0].sec * v[1].sec;
						}
					}
					else{
						if(cur < v[0].fi - i){
							ans = v[0].sec;
							cur = v[0].fi - i;
						}
						else if(cur == v[0].fi - i){
							ans += v[0].sec;
						}
					}
				}
				else{
					if(cur < v[0].fi * 2 - 2 * i){
						ans = v[0].sec * (v[0].sec - 1) / 2;
						cur = v[0].fi * 2 - 2 * i;
					}
					else if(cur == v[0].fi * 2 - 2 * i){
						ans += v[0].sec * (v[0].sec - 1) / 2;
					}
				}
				
				if(batas < 0){
					node now = neg.query(0, sz - 1, 1, 0, i);
					if(cur < now.MX + i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX + i + j;
					}
					else if(cur == now.MX + i + j){
						ans += now.cnt * cur_cnt;
					}
					now = neg.query(0, sz - 1, 1, sz + batas, sz - 1);
					if(cur < now.MX + sz + i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX + sz + i + j;
					}
					else if(cur == now.MX + sz + i + j){
						ans += now.cnt * cur_cnt;
					}				
					now = pos.query(0, sz - 1, 1, i, sz + batas - 1);
					if(cur < now.MX - i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX - i + j;
					}
					else if(cur == now.MX - i + j){
						ans += now.cnt * cur_cnt;
					}
					if(sz % 2 == 0){
						now = pos.query(0, sz - 1, 1, i - sz / 2 + sz, i - sz / 2 + sz);
						if(cur < now.MX - i + j){
							ans = now.cnt * cur_cnt;
							cur = now.MX - i + j;
						}
						else if(cur == now.MX - i + j){
							ans += now.cnt * cur_cnt;
						}
					}
				}
				else{
					node now = neg.query(0, sz - 1, 1, batas, i);
					if(cur < now.MX + i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX + i + j;
					}
					else if(cur == now.MX + i + j){
						ans += now.cnt * cur_cnt;
					}
					now = pos.query(0, sz - 1, 1, 0, batas - 1);
					if(cur < now.MX + sz - i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX + sz - i + j;
					}
					else if(cur == now.MX + sz - i + j){
						ans += now.cnt * cur_cnt;
					}
					now = pos.query(0, sz - 1, 1, i, sz);
					if(cur < now.MX - i + j){
						ans = now.cnt * cur_cnt;
						cur = now.MX - i + j;
					}
					else if(cur == now.MX - i + j){
						ans += now.cnt * cur_cnt;
					}	
					if(sz % 2 == 0){
						now = neg.query(0, sz - 1, 1, i - sz / 2, i - sz / 2);
						if(cur < now.MX + i + j){
							ans = now.cnt * cur_cnt;
							cur = now.MX + i + j;
						}
						else if(cur == now.MX + i + j){
							ans += now.cnt * cur_cnt;
						}
					}			
				}
				
				pos.upd(0, sz - 1, 1, i, {cur_mx, cur_cnt});
				neg.upd(0, sz - 1, 1, i, {cur_mx - 2 * i, cur_cnt});
			}
		}

		cout << ans << "\n";
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...