G小沙的身法 树上前缀和+Tarjan离线求LCA,0%通过

试过很多数据都能过,为什么过不了啊嗷
求大神指点下


#include<iostream>
#include<cstring>
#define ll long long
#define endl "\n"
using namespace std;
const int N = 1e6 + 10;
const int M = 1e5 + 10;
struct Edge {
	int to, nxt;
}edge[2 * N], qedge[2 * M];
int head[N];
int cnt;
int qhead[M];
int qcnt;
bool vis[N],vis2[N];
ll sum[N], resum[N];
int pre[N];
int n, m, x, y, a[N], fa[M], u[M], v[M];

void init()
{
	memset(qhead, -1, sizeof(qhead));
	memset(head, -1, sizeof(head));
	for (int i = 1; i <= n; i++)
		pre[i] = i;
}

void add(int u, int v)
{
	cnt++;
	edge[cnt].to = v;
	edge[cnt].nxt = head[u];
	head[u] = cnt;
}

void add_(int u, int v)
{
	qcnt++;
	qedge[qcnt].to = v;
	qedge[qcnt].nxt = qhead[u];
	qhead[u] = qcnt;
}

int find(int x) {
	return pre[x] == x ? x : pre[x] = find(pre[x]);
}

void join(int x, int y)
{
	x = find(x);
	y = find(y);
	pre[x] = y;
}

void dfs(int u)
{
	vis[u] = true;
	for (int i = head[u]; ~i; i = edge[i].nxt) {
		int v = edge[i].to;
		if (vis[v])
			continue;
		sum[v] = sum[u] + (a[v] > a[u] ? a[v]-a[u] : 0);
		resum[v] = resum[u] + (a[u] > a[v] ? a[u] - a[v] : 0);
		dfs(v);
	}
}

void tarjan(int u)
{
	vis2[u] = true;
	for (int i = head[u]; ~i; i = edge[i].nxt) {
		int v = edge[i].to;
		if (vis2[v])
			continue;
		tarjan(v);
		join(v, u);
	}
	for (int i = qhead[u]; ~i; i = qedge[i].nxt) {
		int v = qedge[i].to;
		if (vis2[v])
			fa[(i + 1) / 2] = find(v);
	}
}

int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin >> n >> m;
	init();
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	for (int i = 1; i < n; i++) {
		cin >> x >> y;
		add(x, y);
		add(y, x);
	}
	for (int i = 1; i <= m; i++) {
		cin >> u[i] >> v[i];
		add_(u[i], v[i]);
		add_(v[i], u[i]);
	}
	dfs(1);
	tarjan(1);
	ll ans;
	for (int i = 1; i <= m; i++) {
		ans = a[u[i]] + (resum[u[i]] - resum[fa[i]]) + (sum[v[i]] - sum[fa[i]]);
		cout << ans << endl;
	}

	return 0;
}

全部评论
ac区千篇一律的倍增lca,没一个Tarjan的,为什么
点赞 回复 分享
发布于 2022-03-26 17:21

相关推荐

自由水:笑死了,敢这么面试不敢让别人说
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务