Educational Codeforces Round 173
Educational Codeforces Round 173
C
记得是处理一下前缀最大值和最小值,后缀最大值和最小值,最后合并即可。这个有讲解,不多赘述。
D
考虑令 ,我们有 。
题目转化为求使得 最大的 ,满足 。
这个我们不难发现, 当然 除外。
所以如果我们从小到大枚举 ,从大到小枚举 ,大概率会找到 的数对。
我们直接暴力枚举:
for (i64 i = l; i <= r && i - l < lim && i - l < res; ++i)
for (i64 j = r; j >= i && r - j < lim && i - l + r - j < res; --j)
if (gcd(i, j) == 1) {
res = min(res, i - l + r - j);
L = i, R = j;
}
这个枚举的复杂度是很低的,我感觉是 的枚举,还有一个 的求 ,但是常数很小。
不妨假设枚举了 ,这时候 显然应该很容易成立。
举个例子,我们要使 对 都不成立,,只有 项。但是反观 的增长代价是很小的, 增长 , 基本上就要乘上一个质数。
我只能说,感性证明,具体证明应该是可以的。
E
这个考虑直接拆位。给定两个 01 矩阵。
能够把某一行改为 ,某一列改为 ,求能否 A -> B
反着考虑?看一下 是否某行为 或者某列为 。
如果是,可以把这行/列从矩阵中删除,然后看剩下的矩阵是否对应。
时间复杂度 。
F
赛时的代码有很多 BUG,不过算法是对的。
首先题目就是求区间中删去若干个数,要求剩下的数异或和为 ,求最多删几个和方案数。
约定:我们下面说的「答案」,指的是保留的数字数量。
首先,我们观察到,当区间长度 满足 的时候,根据鸽巢原理,显然存在 ,我们只需要考虑答案是 还是 。
就是有 , 就是有两个数相同,这都很好处理(具体可见代码,存储每个数出现的位置,然后二分)。
另一方面,当 的时候,根据鸽巢原理,,也就是有 且 ,我们的答案不会超过 。
所以对于 的情况,我们可以去枚举这样的 ,对于 这对,可以用桶,对于 这对,我们直接枚举(钦定 )。可见代码:
Z ans3 = 0, ans2 = 0, ans4 = 0;
array<Z, 64> cnt, cnt2;
for (int i = l; i <= r; ++i) {
for (int j = i + 1; j <= r; ++j) {
ans3 += cnt[a[i] ^ a[j]];
ans4 += cnt2[a[i] ^ a[j]];
if ((a[i] ^ a[j]) == 0) ans2 += 1;
}
cnt[a[i]] += 1;
for (int j = l; j < i; ++j)
cnt2[a[i] ^ a[j]] += 1;
}
这里 ans2, 3, 4
就是选 个数异或和为 的方案数,然后用 cnt[x]
记录前 个数中为 的数的数量,cnt2[x]
记录前 个数中,选两个数的异或和为 的方案数。
时间复杂度 。
对于 的情况,我们直接 枚举每个数选还是不选。
综上,时间复杂度 。
UPD AT 2024/12/25(13:13):经指正,上面这个做法的复杂度是 次方的,我少考虑了枚举 种可能后计算的复杂度。
后经过思考,对于 的情况,应该可以强行再分讨做 的转移,维护 cnt3
。
Z ans3 = 0, ans2 = 0, ans4 = 0, ans5 = 0;
array<Z, 64> cnt, cnt2, cnt3;
for (int i = l; i <= r; ++i) {
for (int j = i + 1; j <= r; ++j) {
ans3 += cnt[a[i] ^ a[j]];
ans4 += cnt2[a[i] ^ a[j]];
ans5 += cnt3[a[i] ^ a[j]]
if ((a[i] ^ a[j]) == 0) ans2 += 1;
}
for (int v = 0; v < 64; ++v)
cnt3[v ^ a[i]] += cnt2[v];
for (int j = l; j < i; ++j)
cnt2[a[i] ^ a[j]] += 1;
cnt[a[i]] += 1;
}
时间复杂度为 。
因为感觉分讨的有点复杂,并且加上维护 cnt3
的启发,我想可以用 f[i][x]
维护保留 个数,异或和为 的方案数解决本题,dp 的代码见下:
f[0][0] = g[0][0] = 1;
for (int i = l; i <= r; ++i)
for (int k = 7; k; --k) {
for (int v = 0; v < 64; ++v) {
f[k][v ^ a[i]] += f[k - 1][v];
g[k][v ^ a[i]] |= g[k - 1][v];
}
}
提交记录298360108,本做法的时间复杂度为 ,但似乎 hack 不掉。hack 记录。
G
没看。
就到这。
本文来自博客园,作者:lingfunny,转载请注明原文链接:https://www.cnblogs.com/lingfunny/p/18629029
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效