我咋又被卡常了。。
  • 板块P4320 道路相遇
  • 楼主_5011_
  • 当前回复3
  • 已保存回复3
  • 发布时间2020/6/15 21:10
  • 上次更新2023/11/7 00:34:45
查看原帖
我咋又被卡常了。。
91127
_5011_楼主2020/6/15 21:10

圆方树,TLE70分,求卡

也许我树链剖分写假了?

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;

inline int qread() {
	register char c = getchar();
	register int x = 0, f = 1;
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + c - 48;
		c = getchar();
	}
	return x * f;
}

inline int Abs(const int& x) {return (x > 0 ? x : -x);}
inline int Max(const int& x, const int& y) {return (x > y ? x : y);}
inline int Min(const int& x, const int& y) {return (x < y ? x : y);}

struct Edge {
	int to, nxt;
	Edge() {
		nxt = -1;
	}
};
struct Graph {
	int hd[1000005], pnt;
	Edge e[4000005];
	Graph() {
		memset(hd, -1, sizeof(hd));
		pnt = 0;
	}
	inline void AddEdge(int u, int v) {
		//printf("%d<->%d\n", u, v);
		e[++pnt].to = v;
		e[pnt].nxt = hd[u];
		hd[u] = pnt;
	}
};
int n, m, dfn[500005], low[500005], _time, bcccnt, dep[1000005], siz[1000005], son[1000005], top[1000005], fa[1000005];
Graph reg, rst;
stack <pair <int, int> > stk;

inline void Read() {
	n = qread(); m = qread();
	for (register int i = 1;i <= m;i++) {
		register int u = qread(), v = qread();
		reg.AddEdge(u, v);
		reg.AddEdge(v, u);
	}
}

inline void Tarjan(int u, int fa) {
	dfn[u] = low[u] = ++_time;
	for (register int i = reg.hd[u];~i;i = reg.e[i].nxt) {
		register int v = reg.e[i].to;
		if (!dfn[v]) {
			stk.push(make_pair(u, v));
			Tarjan(v, u);
			low[u] = Min(low[u], low[v]);
			if (low[v] >= dfn[u]) {
				bcccnt++;
				while (1) {
					register int x = stk.top().first, y = stk.top().second;
					stk.pop();
					rst.AddEdge(y, bcccnt + n);
					rst.AddEdge(bcccnt + n, y);
					if (x == u && y == v) {
						rst.AddEdge(x, bcccnt + n);
						rst.AddEdge(bcccnt + n, x);
						break;
					}
				}
			}
		} else if (dfn[v] < dfn[u] && v != fa) {
			stk.push(make_pair(u, v));
			low[u] = Min(low[u], dfn[v]);
		}
	}
}

inline void Dfs1(int u) {
	siz[u] = 1;
	register int mx = 0;
	for (register int i = rst.hd[u];~i;i = rst.e[i].nxt) {
		if (rst.e[i].to != fa[u]) {
			fa[rst.e[i].to] = u;
			dep[rst.e[i].to] = dep[u] + 1;
			Dfs1(rst.e[i].to);
			siz[u] += siz[rst.e[i].to];
			if (siz[rst.e[i].to] > mx) {
				mx = siz[rst.e[i].to];
				son[u] = rst.e[i].to;
			}
		}
	}
}

inline void Dfs2(int u, int tp) {
	top[u] = tp;
	if (son[u]) Dfs2(son[u], tp);
	for (register int i = rst.hd[u];~i;i = rst.e[i].nxt) {
		if (rst.e[i].to != son[u] && rst.e[i].to != fa[u]) Dfs2(rst.e[i].to, rst.e[i].to);
	}
}

inline int Lca(int u, int v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) return u;
	else return v;
}

inline void Solve() {
	register int q = qread();
	while (q--) {
		register int u = qread(), v = qread();
		register int dis = dep[u] + dep[v] - (dep[Lca(u, v)] << 1);
		printf("%d\n", (dis >> 1) + 1);
	}
}

int main() {
	Read();
	Tarjan(1, -1);
	dep[1] = 1;
	Dfs1(1);
	Dfs2(1, 1);
	Solve();
	#ifndef ONLINE_JUDGE
	while (1);
	#endif
	return 0;
}

2020/6/15 21:10
加载中...