ABC 372

目录

        D. Buildings

        F. K-th Largest Connected Components 


 

 

 

D. Buildings

        如果正着做,对于第 x 个房子会因为前 x - 1个房子当中有高于它的而被挡住,随着 i 往后,高于它的会在界外,那就需要实时判断从 i 到 x - 1 有没有高于它的,显然不可行。

        出现这个问题的原因在于第 x 个房子会受前面房子的影响。但是如果倒过来做,从后往前遍历,显然第 x 个房子不会受到它后面房子的影响,无论后面的房子比它高还是低。

        正解是倒序维护一个单调队列

 

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;

int T, n, cnt, a[N], q[N], ans[N];

signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i ++)
		cin >> a[i];
	int h = 1, t = 0;
	for (int i = n; i >= 1; i --)
	{
		ans[i] = t - h + 1;
		while (h <= t && a[q[t]] < a[i])
			t --;
		q[++ t] = i;
	}
	for (int i = 1; i <= n; i ++)
		cout << ans[i] << ' ';
	return 0;
}

 

 

 

 

 

F. K-th Largest Connected Components 

 

        维护每个集合前 10 大。每个集合要开到 20,拼接后 sort。 维护集合信息都是以每个集合的根节点作为下标。

 

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;

int T, n, q, cnt, ans, fa[N], num[N][20];
string s;

bool cmp(int a, int b)
{
	return a > b;
}

int find(int x)
{
	if (x == fa[x])
		return x;
	return fa[x] = find(fa[x]);
}

void join(int a, int b)
{
	a = find(a), b = find(b);
	if (a != b)
	{
		fa[a] = b;
		for (int i = 1; i <= 10; i ++)
			num[b][i + 10] = num[a][i];
		sort(num[b] + 1, num[b] + 21, cmp);
	}
}

signed main()
{
	cin >> n >> q;
	for (int i = 1; i <= n; i ++)
	{
		fa[i] = i;
		num[i][1] = i;
	}
	while (q --)
	{
		int opt, u, v, k;
		cin >> opt;
		if (opt == 1)
		{
			cin >> u >> v;
			join(u, v);
		}
		if (opt == 2)
		{
			cin >> v >> k;
			v = find(v);
			if (num[v][k] == 0)
				cout << "-1" << '\n';
			else
				cout << num[v][k] << '\n';
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值