HNOI2016 网络

链接

网络

题解

最暴力的想法就是对每个节点维护一个堆,对于每条路径,向不在这条路径上的所有点的堆中插入这条路径的重要度,这肯定会T,考虑用数据结构进行优化。两点之间的路径可以树剖之后用线段树成段更新,但如果通过打 l a z y lazy lazy标记的方法实现成段更新会很麻烦,因为 l a z y lazy lazy标记中要记录每一条路径的信息,下传的时候更是要将每一条路径的信息分别下传,无论时间还是空间都无法接受,这时候就用到了标记永久化的思想,询问的时候只需将从线段树的根节点到该叶节点的路径(也就是所有包含该点的区间)上的值取 m a x max max即可,复杂度 O ( n ( l o g n ) 3 ) O(n(logn)^3) O(n(logn)3).

代码

#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

const int maxn = 100000 + 100;
// const int maxn = 15;
const int maxm = 200000 + 100;
// const int maxm = 30;
const int maxt = 100 + 5;
const int maxk = 1000 + 10;

typedef long long LL;
typedef long double LD;
typedef unsigned long long uLL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;

const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL Inf = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-4;
const double inf = 1e15;
const double pi = acos(-1.0);
const LL mod = 1000000007;

inline int read()
{
	register char c = getchar();
	while (c < '0' || c > '9')
		c = getchar();

	register int x = 0;
	while (c >= '0' && c <= '9')
		x = (x << 3) + (x << 1) + c - '0', c = getchar();

	return x;
}

struct Edge
{
	int to, next;
};

struct Line
{
	int l, r;
	bool operator< (const Line &a)const
	{
		if (l == a.l)
			return r < a.r;
		return l < a.l;
	}
} line[maxn << 1];

struct Graph
{
	Edge edge[maxm];
	int tot, head[maxn];

	void init()
	{
		tot = 1;
		memset(head, 0, sizeof(head));
	}

	void AddEdge(int u, int v)
	{
		edge[tot] = (Edge){v, head[u]};
		head[u] = tot++;
	}
} G;

struct PQ
{
	priority_queue<int> q1, q2;

	void Push(int x)
	{
		q1.push(x);
	}

	void Del(int x)
	{
		q2.push(x);
	}

	int Top()
	{
		while (!q2.empty() && q1.top() == q2.top())
			q1.pop(), q2.pop();
		return q1.empty() ? -1 : q1.top();
	}
} t[maxn << 2];

int n, m, dfs_clock;
int x[maxn << 1], y[maxn << 1], z[maxn << 1];
int dfn[maxn], top[maxn], son[maxn], Size[maxn], fa[maxn], dep[maxn];

void dfs1(int u, int ff)
{
	fa[u] = ff;
	son[u] = 0;
	Size[u] = 1;
	dep[u] = dep[ff] + 1;

	for (int i = G.head[u]; i; i = G.edge[i].next)
	{
		int v = G.edge[i].to;
		if (v == ff)
			continue;
		dfs1(v, u);
		Size[u] += Size[v];
		if (Size[v] > Size[son[u]])
			son[u] = v;
	}
}

void dfs2(int u, int tp)
{
	dfn[u] = ++dfs_clock;
	top[u] = tp;
	if (!son[u])
		return;
	dfs2(son[u], tp);
	for (int i = G.head[u]; i; i = G.edge[i].next)
	{
		int v = G.edge[i].to;
		if (v == fa[u] || v == son[u])
			continue;
		dfs2(v, v);
	}
}

void Update(int L, int R, int x, int opt, int l, int r, int rt)
{
	if (L <= l && r <= R)
	{
		if (opt)
			t[rt].Push(x);
		else
			t[rt].Del(x);
		return;
	}

	int m = (l + r) >> 1;
	if (L <= m)
		Update(L, R, x, opt, lson);
	if (R > m)
		Update(L, R, x, opt, rson);
}

void Happen(int x, int y, int z, int opt)
{
	int tt = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		line[++tt] = (Line){dfn[top[x]], dfn[x]};
		x = fa[top[x]];
	}
	if (dep[x] < dep[y])
		swap(x, y);
	line[++tt] = (Line){dfn[y], dfn[x]};
	sort(line + 1, line + 1 + tt);
	int le = 1;
	for (int i = 1; i <= tt; ++i)
	{
		if (le <= line[i].l - 1)
			Update(le, line[i].l - 1, z, opt, 1, n, 1);
		le = max(le, line[i].r + 1);
	}
	if(le <= n)
		Update(le, n, z, opt, 1, n, 1);
}

int Query(int x, int l, int r, int rt)
{
	if (l == r)
		return t[rt].Top();
	
	int m = (l + r) >> 1;
	int ans = t[rt].Top();
	if (x <= m)
		ans = max(ans, Query(x, lson));
	else
		ans = max(ans, Query(x, rson));
	return ans;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	n = read(), m = read();
	G.init();
	int u, v;
	for (int i = 1; i < n; ++i)
	{
		u = read(), v = read();
		G.AddEdge(u, v), G.AddEdge(v, u);
	}

	dfs1(1, 0);
	dfs2(1, 1);

	int opt, tmp;
	for (int i = 1; i <= m; ++i)
	{
		opt = read();
		if (!opt)
		{
			x[i] = read(), y[i] = read(), z[i] = read();
			Happen(x[i], y[i], z[i], 1);
		}
		else if (opt == 1)
		{
			tmp = read();
			Happen(x[tmp], y[tmp], z[tmp], 0);
		}
		else
		{
			tmp = read();
			cout << Query(dfn[tmp], 1, n, 1) << "\n";
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值