35 分求助
查看原帖
35 分求助
555825
block_in_mc楼主2023/12/27 21:15
#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
const int N = 200100;
struct node { ll l, r, lcm; ull sum; } tr[4*N];
ll n, m, a[N];
ll gcd(ll x, ll y) {
    ll tmp;
    while (x % y != 0)
        tmp = x % y, x = y, y = tmp;
    return y;
}
void push_up(ll id) {
    ll l = id * 2, r = id * 2 + 1;
    tr[id].sum = tr[l].sum + tr[r].sum;
    if (tr[l].lcm == -1 || tr[r].lcm == -1) {
        tr[id].lcm = -1;
        return;
    }
    __int128 lcm = (__int128) tr[l].lcm * tr[r].lcm / gcd(tr[l].lcm, tr[r].lcm);
    if (lcm > (__int128) 1e18) tr[id].lcm = -1;
    else tr[id].lcm = (ll) lcm;
}
void build(ll id, ll l, ll r) {
    tr[id].l = l, tr[id].r = r;
    if (l == r) {
        tr[id].sum = tr[id].lcm = a[l];
        return;
    }
    ll mid = (l + r) / 2;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);
    push_up(id);
}
void update(ll id, ll l, ll r, ll x) {
    if (tr[id].lcm != -1 && x % tr[id].lcm == 0)
        return;
    if (tr[id].l == tr[id].r) {
        tr[id].sum = tr[id].lcm = gcd(tr[id].lcm, x);
        return;
    }
    ll mid = (tr[id].l + tr[id].r) / 2;
    if (l <= mid) update(id * 2, l, r, x);
    if (r > mid) update(id * 2 + 1, l, r, x);
    push_up(id);
}
ull query(ll id, ll l, ll r) {
    if (tr[id].l >= l && tr[id].r <= r)
        return tr[id].sum;
    ull ans = 0, mid = (tr[id].l + tr[id].r) / 2;
    if (l <= mid) ans += query(id * 2, l, r);
    if (r > mid) ans += query(id * 2 + 1, l, r);
    return ans;
}
int main() {
    scanf("%lld%lld", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
    build(1, 1, n);
    ll op, l, r, x;
    for (int i = 1; i <= m; i++) {
        scanf("%lld%lld%lld", &op, &l, &r);
        if (op == 1) {
            scanf("%lld", &x);
            update(1, l, r, x);
        }
        if (op == 2)
            printf("%llu\n", query(1, l, r));
    }
    return 0;
}
2023/12/27 21:15
加载中...