首页 > 其他分享 >CF1468M

CF1468M

时间:2022-10-16 08:55:06浏览次数:48  
标签:CF1468M int 元素 sqrt vis 序列 define

首先先将所有元素离散化。

设 \(m=\sum k_i\),因为 \(n,m\) 同阶,所以下文均用 \(n\) 来表示。

考虑根号分治。

  • 对于元素个数超过 \(\sqrt n\) 的序列,不难发现这样的序列至多只有 \(\sqrt n\) 个。对于每个序列,把它的元素存进桶中,然后枚举其它所有的序列来判断。这部分时间复杂度是 \(\mathcal O(n\sqrt n)\) 的。

  • 对于元素个数不超过 \(\sqrt n\) 的序列,枚举这些序列的元素对 \((x,y)\),并把它们存储下来,进行判断。对于 \(\sum_{k_i\lt \sqrt n}\frac{k_i\times (k_i-1)}{2}\),不难发现最大也才 \(n\sqrt n\),所以这部分的时间复杂度也是 \(\mathcal O(n\sqrt n)\) 的。

实现时候需要精细一点,否则可能会 MLE。

具体细节看代码。

Code:

#include <bits/stdc++.h>
using namespace std;
#define siz(a) a.size()
#define pb push_back
#define fi first
#define se second
typedef pair <int, int> pii;
const int N = 200005;
int T;
int n, m, cnt;
int vis[N];
vector <int> v, b, a[N];
vector <pii> vec[N];

void init() {
	v.clear(), b.clear(), m = 0;
	for (int i = 1; i <= n; ++i) a[i].resize(1);
}

void solve() {
	scanf("%d", &n), init();
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i][0]), m += a[i][0], a[i].resize(a[i][0] + 1);
		for (int j = 1; j <= a[i][0]; ++j) scanf("%d", &a[i][j]), b.pb(a[i][j]);
		sort(++a[i].begin(), a[i].end());
	}
	m = sqrt(m) / 2, sort(b.begin(), b.end()), b.erase(unique(b.begin(), b.end()), b.end());
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= a[i][0]; ++j)
			a[i][j] = lower_bound(b.begin(), b.end(), a[i][j]) - b.begin() + 1;
	for (int i = 1; i <= n; ++i) {
		if (a[i][0] > m) {
			cnt = 0;
			memset(vis + 1, 0, sizeof (int) * siz(b));
			for (int j = 1; j <= a[i][0]; ++j) vis[a[i][j]] = 1;
			for (int j = 1; j <= n; ++j) if (i != j) {
				cnt = 0;
				for (int k = 1; k <= a[j][0]; ++k) {
					++vis[a[j][k]], cnt += (vis[a[j][k]] == 2);
					if (cnt == 2) return printf("%d %d\n", i, j), void();
				}
				for (int k = 1; k <= a[j][0]; ++k) --vis[a[j][k]];
			}
		}
		else v.pb(i);
	}
	memset(vis + 1, 0, sizeof (int) * siz(b));
	for (int i = 1; i <= siz(b); ++i) vec[i].clear();
	for (auto i : v)
		for (int j = 1; j <= a[i][0]; ++j)
			for (int k = j + 1; k <= a[i][0]; ++k)
				vec[a[i][j]].pb(pii(a[i][k], i));
	for (int i = 1; i <= siz(b); ++i) {
		for (auto j : vec[i]) {
			if (vis[j.fi]) return printf("%d %d\n", vis[j.fi], j.se), void();
			vis[j.fi] = j.se;
		} 
		for (auto j : vec[i]) vis[j.fi] = 0;
	}
	printf("%d\n", -1);
}

int main() {
	scanf("%d", &T);
	while (T--) solve();
	return 0;
}

标签:CF1468M,int,元素,sqrt,vis,序列,define
From: https://www.cnblogs.com/Kobe303/p/16795606.html

相关文章