CF1609F Interesting Sections 题解
分治,设当前区间为
枚举区间左端点
, 的 均落在 中,
则若此时
, 的 一个落在 中,一个落在 中,
以
问题变为统计
直接开桶维护
, 的 均落在 中,
问题变为统计
发现与
然后倒序枚举
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
int n, q, a[1000050], e[1000050], c1[70], c2[70];
void F(int l, int r)
{
if (l == r)
return void(++q);
int m = l + r >> 1;
memset(c1, 0, sizeof c1);
memset(c2, 0, sizeof c2);
e[m] = 0;
long long u = 1e18, v = -1e18, u1 = 1e18, v1 = -1e18, u2 = 1e18, v2 = -1e18;
for (int i = m + 1; i <= r; ++i)
e[i] = e[i - 1] + (__builtin_popcountll(u = min(u, a[i])) == __builtin_popcountll(v = max(v, a[i])));
u = 1e18;
v = -1e18;
for (int i = m, p1 = m, p2 = m; i >= l; --i)
{
u = min(u, a[i]);
v = max(v, a[i]);
while (p1 < r && u <= min(u1, a[p1 + 1]) && v >= max(v1, a[p1 + 1]))
u1 = min(u1, a[++p1]), v1 = max(v1, a[p1]), --c1[__builtin_popcountll(u1)], --c2[__builtin_popcountll(v1)];
while (p2 < r && (u <= min(u2, a[p2 + 1]) || v >= max(v2, a[p2 + 1])))
u2 = min(u2, a[++p2]), v2 = max(v2, a[p2]), ++c1[__builtin_popcountll(u2)], ++c2[__builtin_popcountll(v2)];
if (__builtin_popcountll(u) == __builtin_popcountll(v))
q += p1 - m;
q += e[r] - e[p2];
if (u <= u2)
q += c2[__builtin_popcountll(u)];
else
q += c1[__builtin_popcountll(v)];
}
F(l, m);
F(m + 1, r);
}
signed main()
{
scanf("%lld", &n);
for (int i = 1; i <= n; ++i)
scanf("%lld", a + i);
F(1, n);
printf("%lld", q);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具