제출 #1242204

#제출 시각아이디문제언어결과실행 시간메모리
1242204altern23관광지 (IZhO14_shymbulak)C++20
0 / 100
29 ms12868 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];
pii dp[MAXN + 5];

void dfs2(ll idx, ll par){
	vis[idx] = 1;
	dp[idx] = {d[idx], 1};
	for(auto i : adj[idx]){
		if(!vis[i] && !cycle[i]){
			d[i] = d[idx] + 1;
			dfs2(i, idx);
			if(dp[idx].fi < dp[i].fi) dp[idx] = dp[i];
			else if(dp[idx].fi == dp[i].fi) dp[idx].sec += dp[i].sec;
		}
	}
}

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);
	}
	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;
		
		vector<pair<ll, pii>> isi;
		ll cur = 0, ans = 0;
		for(int tt = 1; tt <= N; tt++){
			if(cycle[tt]){
				dfs2(tt, -1);
				ll MX = d[tt], MX2 = -INF;
				for(auto i : adj[tt]){
					if(!cycle[i]){
						MX2 = max(MX2, dp[i].fi);
						if(MX < MX2) swap(MX, MX2);
					}
				}
				
				vector<ll> v;
				ll cnt = (MX == d[tt]), cntt = 0;
				for(auto i : adj[tt]){
					if(!cycle[i]){
						if(dp[i].fi == MX){
							v.push_back(dp[i].sec);
							cnt += dp[i].sec;
						}
						if(dp[i].fi == MX2) cntt += dp[i].sec;
					}
				}
				if(v.size() > 1){
					for(auto x : v){
						ans += (cnt - x) * x;
					}
				}
				else{
					if(!cntt) ans += cnt * 2;
					else ans += cnt * cntt * 2;
				}
				
				ll i = d[tt], j = MX - i;
				isi.push_back({i, {j, cnt}});
				pos.upd(0, sz - 1, 1, i, {MX, cnt});
				neg.upd(0, sz - 1, 1, i, {MX - 2 * i, cnt});
			}
		}
		
		for(auto [i, val] : isi){
			ll j = val.fi, cur_cnt = val.sec;
			ll batas = i - sz / 2;
			if(batas < 0){
				node now = neg.query(0, sz - 1, 1, 0, i - 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;
				}
				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 + 1, 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 - 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;
				}
				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 + 1, 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;
					}
				}			
			}
		}

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