CF920F SUM and REPLACE 题解

Posted whx666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF920F SUM and REPLACE 题解相关的知识,希望对你有一定的参考价值。

CF920F SUM and REPLACE

线段树例题解析合集

和模板的不同之处在于修改时是改为每个数的约数个数,不难发现,当一个数x<=2时,x的约数个数与本身相等,修改多少次多不会在改变

先预处理出每个数的约数个数,用线段树维护区间最大值,若<=2,则直接结束递归

对于>2的数都要暴力修改,但由于每个数的约数个数下降很快,几次后便降到<=2,所以复杂度优秀(大约是nlogn?)

这题与CF438D The Child and Sequence(区间取模),类似,也可以维护区间最大值

CF920F:

#include <bits/stdc++.h>
using namespace std;
#define rg register
#define ll long long
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch))  x = x * 10 + ch - 48, ch = getchar();
}
void print (ll x) {
    if (x > 9) print (x / 10);
    putchar (x % 10 + 48);
}
const int N = 3e5 + 10, M = 1e6;
int n, m, opt, ql, qr, cnt, maxn, p[N], a[N], k[M + 10], num[M + 10], c[N << 2];
ll s[N << 2];
inline void pre_work () {
    num[1] = 1;
    for (rg int i = 2; i <= maxn; ++i) {
        if (!k[i]) p[++cnt] = i, num[i] = 2;
        for (rg int j = 1; j <= cnt && p[j] * i <= maxn; ++j) {
            int tmp (p[j] * i), t (0);
            while (tmp % p[j] == 0) ++t, tmp /= p[j];
            k[p[j] * i] = 1, num[p[j] * i] = num[tmp] * (t + 1);
            if (i % p[j] == 0) continue;
        }
    }
}
#define ls p << 1
#define rs p << 1 | 1
inline int Max (int a, int b) {return a > b ? a : b;}
inline void push_up (int p) {
    s[p] = s[ls] + s[rs], c[p] = Max (c[ls], c[rs]);
}
void build (int p, int l, int r) {
    if (l == r) {c[p] = s[p] = a[l]; return;}
    int mid = l + r >> 1;
    build (ls, l, mid), build (rs, mid + 1, r);
    push_up (p);
}
void update (int p, int l, int r) {
    if (c[p] <= 2) return;
    if (l == r) {c[p] = s[p] = num[c[p]]; return;}
    int mid = l + r >> 1;
    if (ql <= mid) update (ls, l, mid);
    if (qr > mid) update (rs, mid + 1, r);
    push_up (p);
}
ll ask (int p, int l, int r) {
    if (ql <= l and qr >= r) return s[p];
    ll s (0);  int mid = l + r >> 1;
    if (ql <= mid) s += ask (ls, l, mid);
    if (qr > mid) s += ask (rs, mid + 1, r);
    return s;
}
int main() {
    read (n), read (m);
    for (rg int i = 1; i <= n; ++i) read (a[i]), maxn = Max (maxn, a[i]);
    pre_work (), build (1, 1, n);
    for (rg int i = 1; i <= m; ++i) {
        read (opt);
        if (opt == 1) read (ql), read (qr), update (1, 1, n);
        else read (ql), read (qr), print (ask (1, 1, n)), puts ("");
    }
    return 0;
}

CF438D:

#include <bits/stdc++.h>
using namespace std;
#define rg register
#define ll long long
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch))  x = x * 10 + ch - 48, ch = getchar();
}
void print (ll x) {
    if (x > 9) print (x / 10);
    putchar (x % 10 + 48);
}
const int N = 1e5 + 10;
int n, m, opt, ql, qr, mod, val, pos, a[N], c[N << 2];
ll s[N << 2];
#define ls p << 1
#define rs p << 1 | 1
inline int Max (int a, int b) {return a > b ? a : b;}
inline void push_up (int p) {
    s[p] = s[ls] + s[rs], c[p] = Max (c[ls], c[rs]);
}
void build (int p, int l, int r) {
    if (l == r) {c[p] = s[p] = a[l]; return;}
    int mid = l + r >> 1;
    build (ls, l, mid), build (rs, mid + 1, r);
    push_up (p);
}
void update (int p, int l, int r) {
    if (c[p] < mod) return;
    if (l == r) {c[p] %= mod, s[p] %= mod; return;}
    int mid = l + r >> 1;
    if (ql <= mid) update (ls, l, mid);
    if (qr > mid) update (rs, mid + 1, r);
    push_up (p);
}
void change (int p, int l, int r) {
    if (l == r) {c[p] = s[p] = val; return;}
    int mid = l + r >> 1;
    (pos <= mid) ? change (ls, l, mid) : change (rs, mid + 1, r);
    push_up (p);
}
ll ask (int p, int l, int r) {
    if (ql <= l and qr >= r) return s[p];
    ll s (0);  int mid = l + r >> 1;
    if (ql <= mid) s += ask (ls, l, mid);
    if (qr > mid) s += ask (rs, mid + 1, r);
    return s;
}
int main() {
    read (n), read (m);
    for (rg int i = 1; i <= n; ++i) read (a[i]);
    build (1, 1, n);
    for (rg int i = 1; i <= m; ++i) {
        read (opt);
        if (opt == 1) {
            read (ql), read (qr);
            print (ask (1, 1, n)), puts ("");
        }
        else if (opt == 2) {
            read (ql), read (qr), read (mod);
            update (1, 1, n);
        }
        else {
            read (pos), read (val);
            change (1, 1, n);
        }
    }
    return 0;
}

以上是关于CF920F SUM and REPLACE 题解的主要内容,如果未能解决你的问题,请参考以下文章

codeforces CF920F SUM and REPLACE 线段树 线性筛约数

Codefroces 920F SUM and REPLACE???????????????

codeforces 920F SUM and REPLACE

Codeforces 920F - SUM and REPLACE

CodeForces - 920F SUM and REPLACE (线段树)

题解 SP2713 GSS4 - Can you answer these queries IV