列表

详情


NC223457. 小䓤的石头

描述

给定 n 个从 1n 编号的二元组 (a_i,b_i) 和一个大整数 k

对不可重数集 S 定义 F_k(S) 表示将 S 个子集的异或和排序后的第 k 个元素。

,将其所有子集的异或和排序后写出来为,那么有


求最小的 len 使得 ,其中 表示所有 a_i 组成的集合。

保证 是一个合法区间。

输入描述

第一行一个整数表示 n

接下来 n 行,第 行两个整数为 a_i,b_i 用空格隔开。

行一个无前导零 K 代表 k-1 的二进制表示,从左往右是高位到低位。(样例解释中有体现。)

行一个整数s

输出描述

一个整数表示最小区间大小()

示例1

输入:

10
16 272
8 60
1 392
24 352
16 188
1 130
8 161
24 121
24 117
24 156
111
7

输出:

39

说明:

读入有k=(111)_2-1=6

[117,156] 是一个合法区间,F_6(\{a_i\mid b_i\in[117,156]\})=1\leqslant 7,并且容易证明不存在 r-l<156-117=39 的合法区间,所以答案为 39

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 66ms, 内存消耗: 1968K, 提交时间: 2021-11-19 20:12:44

#include <bits/stdc++.h>
using namespace std;

typedef long long s64;
const int N = 1e5 + 5, D = 998244353, L = 63;
s64 pow_mod(s64 x, int y = D - 2) {
	s64 ans = 1;
	while (y) {
		if (y & 1) ans = ans * x % D;
		x = x * x % D;
		y >>= 1;
	}
	return ans;
}
pair<int, s64> p[N];
char K[N];
s64 a[L];
int t[L];
void ins(s64 na, int nt) {
	for (int i = L - 1; i >= 0; --i)
		if ((na >> i) & 1) {
			if (!a[i]) {
				a[i] = na;
				t[i] = nt;
				break;
			}
			if (nt > t[i]) {
				swap(nt, t[i]);
				swap(a[i], na);
			}
			na ^= a[i];
		}
}
int n, len_K;
bool check(int l, int r, s64 s) {
	if (r - l + 1 < len_K) return 0;
	int m = r - l + 1, c = 0;
	for (int i = L - 1; i >= 0; --i)
		if (t[i] >= l) {
			--m;
			++c;
		}
	int p = len_K - m;
	if (p < 0) return 1;
	s64 ans = 0;
	int head = p - c;
	for (int i = L - 1; i >= 0; --i) {
		if (t[i] >= l) {
			++head;
			if (head >= 1 && K[head] == '1')
				ans = max(ans, a[i] ^ ans);
			else
				ans = min(ans, a[i] ^ ans);
		}
	}
	return ans <= s;
}

int main() {
#ifdef kcz
	freopen("1.in", "r", stdin); //freopen("1.out","w",stdout);
#endif
	cin >> n;
	for (int i = 1; i <= n; ++i) scanf("%lld%d", &p[i].second, &p[i].first);
	sort(p + 1, p + n + 1);
	scanf("%s", K + 1);
	len_K = strlen(K + 1);
	s64 s;
	cin >> s;
	int l = 1;
	int ans = 2e9;
	for (int r = 1; r <= n; ++r) {
		ins(p[r].second, r);
		while (check(l, r, s)) {
			ans = min(ans, p[r].first - p[l].first);
			++l;
		}
	}
	cout << ans << endl;
}

上一题