连掉了五场分,但是该打还是要打。反正也不会更差了。
problem set
官方中解
A
我A就不会了,但是随便猜了一个结论过了。
复制一下题解:考虑移除连续33实际减少的数是多少,就会发现减少的也是33倍数,所以原本就要整除才行
B
呃一开始构造错了。。把最小数间隔k排然后别的数随便塞
C
\(O(n)\) 加强版:需要观察到因为前面全是连续1所以只要找第一段和连续0匹配的就可以
D
想要知道如何选择题目会使答案最小。就会发现每次只和最小的无法解答的题目有关。
应该说一开始以为是贪心选最大一些题目。后面发现应该是前面选一段题目中间空一段不选(m%k个)然后选最后一段题目。
然后就卡死在实现这个鬼东西上面了。
呃最后发现可以直接把前面这一段直接挪到最后去先选掉(相当于排序),就可以贪心选择了。
复杂度为调和级数
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
#define lowbit(x) (x & (-x))
#define endl '\n'
#define int long long
#define pii pair<int, int>
#define mkp make_pair
#define LL long long
int n, k, m, a[N], b[N], suf[N];void solve()
{cin >> n >> m;int k = 0;for (int i = 1; i <= n; i++) {cin >> a[++k];if (i > 1 && a[k] < a[1]) k--;}n = k; k = 0;for (int i = 1; i <= m; i++) {cin >> b[i];if (b[i] <= a[1]) b[i] = 0x3f3f3f3f;}sort(b + 1, b + m + 1); sort(a + 1, a + n + 1);for (int i = m, j = n; i >= 1; i--) {while(j > 0 && b[i] <= a[j]) j--;suf[i] = n - j + 1;}for (int k = 1; k <= m; k++) {int sum = 0;for (int i = m % k + 1; i <= m - k + 1; i += k) sum += suf[i];cout << sum << ' ';}cout << endl;
}signed main()
{ios::sync_with_stdio(false);cin.tie(nullptr);int T = 1;cin >> T;while (T--) {solve();}return 0;
}
E
每种颜色都没有环,也就是会构成一颗树或者森林
一棵树节点为m+2n时最多有m+2n-1条边,所以(m+2n-1)* n >= 2nm, 2n-1 >= m