CF474F Ant colony 题解

线段树。

i 得到满分,则 j[l,r],si|sj,即 si=gcdj=lrsj

即求区间 gcd 出现次数,可以类比区间 min 出现次数写。

#include <cstdio>
#include <algorithm>
using namespace std;
int n, m, g[100050 << 2], v[100050 << 2];
void B(int s, int t, int p)
{
    if(s == t) return (void)(scanf("%d", g + p), v[p] = 1);
    int m = s + t >> 1;B(s, m, p << 1);B(m + 1, t, p << 1 | 1);
    g[p] = __gcd(g[p << 1], g[p << 1 | 1]);
    if(g[p] == g[p << 1]) v[p] += v[p << 1];
    if(g[p] == g[p << 1 | 1]) v[p] += v[p << 1 | 1];
}
int G(int l, int r, int s, int t, int p)
{
    if(l <= s && t <= r) return g[p];int m = s + t >> 1;
    if(l <= m && r > m) return __gcd(G(l, r, s, m, p << 1), G(l, r, m + 1, t, p << 1 | 1));
    if(l <= m) return G(l, r, s, m, p << 1);if(r > m) return G(l, r, m + 1, t, p << 1 | 1);
}
int Q(int l, int r, int k, int s, int t, int p)
{
    if(l <= s && t <= r) return v[p] * (g[p] == k);int m = s + t >> 1, q = 0;
    if(l <= m) q += Q(l, r, k, s, m, p << 1);if(r > m) q += Q(l, r, k, m + 1, t, p << 1 | 1);return q;
}
int main()
{
    scanf("%d", &n);B(1, n, 1);scanf("%d", &m);
    for(int i = 0, x, y;i < m;++i)
        scanf("%d%d", &x, &y), printf("%d\n", y - x + 1 - Q(x, y, G(x, y, 1, n, 1), 1, n, 1));
    return 0;
}
posted @   Jijidawang  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示