3 条题解
-
0
显然,每一维有两个方向,所以 维一共有 个方向。所求即为对于 个方向中的每一种方向,最大的合法 之和。
直接枚举复杂度为 或 ,考虑优化,假设有一维的某一个方向最大的合法 非常小,那么确定这一维之后,剩下 维的 种情况的贡献都会为这一维的 ,这启发我们对每一维的每一个方向拆贡献计算。
我们希望当前的 是所有方向的最小值,所以可以按照每一维,每个方向的最大合法 共 个数从小到大排序,然后倒序处理。考虑我们枚举到这个数是维度 的某一个方向的最大合法 ,显然,如果到此时出现过的不同的维度(含 )小于 个,则说明当前数不可能作为最小值,所以没有贡献,否则,答案加上这个数乘以这个数的贡献系数即可。假设这个数后面有 个维度出现了两次(含这个数所在的维度),则贡献系数为 ,这个可以在倒序枚举时计算出来,只要维护一个 表示贡献系数,在一个维度第二次出现时令 即可。
#include <bits/stdc++.h> using namespace std; const int N = 4e5 + 5, mod = 1e9 + 7; int n, a[N], f[N]; pair<int, int> b[N]; signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n; for(int i = 1; i <= n; i++) cin >> a[i]; for(int i = 1, x; i <= n; i++) { cin >> x; b[i] = {x - 1, i}, b[n + i] = {a[i] - x, i}; } sort(b + 1, b + 2 * n + 1); int t = 1, ans = 1, cnt = 0; for(int i = 2 * n; i >= 1; i--) { auto [v, id] = b[i]; cnt += !f[id]; if(cnt == n) ans = (ans + 1ll * t * v % mod) % mod; if(f[id]) t = t * 2 % mod; f[id] = 1; } cout << ans << '\n'; return 0; }
信息
- ID
- 82
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 407
- 已通过
- 82
- 上传者