CF 475D.CGCDSSQ ST表 + 二分

题目链接

题意:

给定长度为 n n n的正整数序列 a a a
m m m组询问,每组询问包括一个正整数 x x x
对每个询问计算共有多少个区间 [ l , r ] [l,r] [l,r],满足 a l , a l + 1 , … , a r a_l,a_{l+1},\dots,a_r al,al+1,,ar的最大公约数为 x x x,即 g c d ( a l , a l + 1 , … , a r ) = x gcd(a_l,a_{l+1},\dots,a_r)=x gcd(al,al+1,,ar)=x

数据范围:
在这里插入图片描述
题解:

1.首先,我们使用 S T ST ST表存储区间之间的最大公约数。

2.对每个询问 x x x,枚举左端点 L L L

①对每个左端点 L L L,在最大公约数为 g g g的情况下,计算出满足 g c d ( [ L , R ] ) = g gcd([L,R])=g gcd([L,R])=g的最大的 R R R g g g初始化为 s t [ L ] [ 0 ] st[L][0] st[L][0]

②那么对于最大公约数为 g g g,且左端点为 L L L的情况下,满足条件的区间个数为 R − L + 1 R -L+1 RL+1。接着我们将 g g g更新为 g c d ( [ L , R + 1 ] ) gcd([L,R+1]) gcd([L,R+1]),重复之前的操作,直到 R > n R>n R>n

由于区间的最大公约数随着区间右端点的不断增加,具有不增加的性质,因此,我们可以对右端点 R R R进行二分查找。

此时, g c d ( a , b ) = m i n ( a , b ) 且 g c d ( a , b ) ≤ m i n ( a , b ) 2 gcd(a,b)=min(a,b)且gcd(a,b) \leq \frac{min(a,b)}2 gcd(a,b)=min(a,b)gcd(a,b)2min(a,b),此时, g c d gcd gcd最多只会变化 l o g n logn logn次,也就是第 2 2 2步最多只会执行 l o g n logn logn次。

我们在 O ( n ) O(n) O(n)枚举左端点的同时,二分查找满足条件的最大右端点,因此时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

实现细节见代码:

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
const int mod = 1e9 + 7;
int st[MAXN][30], logn[MAXN], a[MAXN];
map<int, int> ans;
void init() {
    logn[1] = 0;
    for (int i = 2; i < MAXN; i++) {
        logn[i] = logn[i / 2] + 1;
    }
}
void get_st(int n) {
    for (int j = 1; j <= 25; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            st[i][j] = __gcd(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int query(int l, int r) {
    int k = logn[r - l + 1];
    return __gcd(st[l][k], st[r - (1 << k) + 1][k]);
}
int check(int g, int L, int l, int n) {
    int r = n;
    while (l < r) {
        int mid = l + r >> 1;
        if (query(L, mid) != g) {
            r = mid;
        }
        else {
            l = mid + 1;
        }
    }
    if (query(L, l) != g) l--; // 注意特判当前l是否符合要求
    return l;
}
void solve(int l, int n) {
    int r = l, g = st[l][0];
    while (r <= n) {
        int pre = r;
        r = check(g, l, r, n); // 二分满足区间公约数为g的最大右端点
        ans[g] += r - pre + 1;
        g = query(l, r + 1);
        r++;
    }
}
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        st[i][0] = a[i];
    }
    init();
    get_st(n);
    for (int i = 1; i <= n; i++) { // 枚举左端点
        solve(i, n);
    }
    int q;
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        cout << ans[x] << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
goroutine 52 [select]: github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher.func1() D:/Program Files (x86)/Go/bin/pkg/mod/github.com/go-sql-driver/mysql@v1.7.1/connection.go:614 +0xaf created by github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher D:/Program Files (x86)/Go/bin/pkg/mod/github.com/go-sql-driver/mysql@v1.7.1/connection.go:611 +0x10a goroutine 83 [select]: github.com/go-redis/redis/v8/internal/pool.(*ConnPool).reaper(0x12f262a0, 0xdf8475800) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/go-redis/redis/v8@v8.11.5/internal/pool/pool.go:485 +0xd6 created by github.com/go-redis/redis/v8/internal/pool.NewConnPool D:/Program Files (x86)/Go/bin/pkg/mod/github.com/go-redis/redis/v8@v8.11.5/internal/pool/pool.go:111 +0x242 goroutine 85 [chan receive]: go-study/models.sendProc(0x12e40cf0) D:/go/go-study/models/Message.go:88 +0x48 created by go-study/models.Chat D:/go/go-study/models/Message.go:79 +0x30d goroutine 86 [IO wait]: internal/poll.runtime_pollWait(0x33340b00, 0x72) D:/Program Files (x86)/Go/src/runtime/netpoll.go:305 +0x52 internal/poll.(*pollDesc).wait(0x138f60f4, 0x72, 0x0) D:/Program Files (x86)/Go/src/internal/poll/fd_poll_runtime.go:84 +0x37 internal/poll.execIO(0x138f6014, 0xa365e0) D:/Program Files (x86)/Go/src/internal/poll/fd_windows.go:175 +0xfc internal/poll.(*FD).Read(0x138f6000, {0x12f41000, 0x1000, 0x1000}) D:/Program Files (x86)/Go/src/internal/poll/fd_windows.go:441 +0x13b net.(*netFD).Read(0x138f6000, {0x12f41000, 0x1000, 0x1000}) D:/Program Files (x86)/Go/src/net/fd_posix.go:55 +0x3f net.(*conn).Read(0x12c0aa68, {0x12f41000, 0x1000, 0x1000}) D:/Program Files (x86)/Go/src/net/net.go:183 +0x4f bufio.(*Reader).fill(0x12d1eae0) D:/Program Files (x86)/Go/src/bufio/bufio.go:106 +0xe9 bufio.(*Reader).Peek(0x12d1eae0, 0x2) D:/Program Files (x86)/Go/src/bufio/bufio.go:144 +0x6d github.com/gorilla/websocket.(*Conn).read(0x12f68000, 0x2) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gorilla/websocket@v1.5.0/conn.go:371 +0x30 github.com/gorilla/websocket.(*Conn).advanceFrame(0x12f68000) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gorilla/websocket@v1.5.0/conn.go:809 +0xae github.com/gorilla/websocket.(*Conn).NextReader(0x12f68000) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gorilla/websocket@v1.5.0/conn.go:1009 +0xb5 github.com/gorilla/websocket.(*Conn).ReadMessage(0x12f68000) D:/Program Files (x86)/Go/bin/pkg/mod/github.com/gorilla/websocket@v1.5.0/conn.go:1093 +0x25 go-study/models.recvProc(0x12e40cf0) D:/go/go-study/models/Message.go:100 +0x105 created by go-study/models.Chat D:/go/go-study/models/Message.go:81 +0x352
06-02

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值