zoukankan      html  css  js  c++  java
  • CF920F 【SUM and REPLACE】

    题面

    题意:

    1:将 [l,r]区间内的所有数变为当前权值的正约数的个数,即:(a_i)=d(a_i)

    2:求(displaystyle sum_{i=l}^{r}a_{i})

    前置芝士:

    (d(i))的话,可以先康康这个题P6810 「MCOI-02」Convex Hull 凸包

    这个题中就是线性筛处理出了每个数的约数的个数

    这里安利一个同机房dalao的博客

    我们就可以发现每个数的约数的个数就可以处理出来了

    void make_d(){
        d[1] = f[1] = 1;
        for(int i = 2; i <= M - 5; i ++){
            if(!is_pri[i]){
                pri[++ cnt] = i;
                f[i] = 1;
                d[i] = 2;
            }
            for(int j = 1; j <= cnt && i * pri[j] <= M - 5; j ++){
                is_pri[i * pri[j]] = 1;
                if(i % pri[j] == 0){
                    f[i * pri[j]] = f[i] + 1;
                    d[i * pri[j]] = (d[i]) * (f[i * pri[j]] + 1) / (f[i] + 1);
                    break;
                }
                f[i * pri[j]] = 1;
                d[i * pri[j]] = d[i] * d[pri[j]];
            }
        }
    }
    

    实现:

    我们先用线性筛筛出每个数的约数的个数

    然后维护一棵线段树,线段树维护一个区间(sum)和区间最大值

    我们考虑当(i=1或2)的时候,(d(i))是等于(i)的,所以不用修改

    所以当区间最大值(<=2)的时候,我们就可以不对这个区间进行任何修改操作了(因为操作了也没有任何意义)

    然后就是维护一棵普通的线段树就好了

    但是这个题要注意开$long long $,不然会炸的

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ls(o) (o << 1)
    #define rs(o) (o << 1 | 1)
    #define mid ((l + r) >> 1)
    const int N = 3e5 + 5, M = 1e6 + 5;
    int n, m, a[N], pri[N], cnt;
    long long mx[N << 2], tr[N << 2], d[M], f[M];
    bool is_pri[M];
    void make_d(){
        d[1] = f[1] = 1;
        for(int i = 2; i <= M - 5; i ++){
            if(!is_pri[i]){
                pri[++ cnt] = i;
                f[i] = 1; d[i] = 2;
            }
            for(int j = 1; j <= cnt && i * pri[j] <= M - 5; j ++){
                is_pri[i * pri[j]] = 1;
                if(i % pri[j] == 0){
                    f[i * pri[j]] = f[i] + 1;
                    d[i * pri[j]] = (d[i]) * (f[i * pri[j]] + 1) / (f[i] + 1);
                    break;
                }
                f[i * pri[j]] = 1;
                d[i * pri[j]] = d[i] * d[pri[j]];
            }
        }
    }
    void up(int o){
        tr[o] = tr[ls(o)] + tr[rs(o)];
        mx[o] = max(mx[ls(o)], mx[rs(o)]);
    }
    void build(int o, int l, int r){
        if(l == r){
            scanf("%d", &tr[o]);
            mx[o] = tr[o];
            return ;
        }
        build(ls(o), l, mid); build(rs(o), mid + 1, r);
        up(o);
    }
    void change(int o, int l, int r, int L, int R){
        if(mx[o] <= 2) return ;
        if(l == r){
            tr[o] = mx[o] = d[tr[o]];
            return ;
        }
        if(L <= mid) change(ls(o), l, mid, L, R);
        if(R > mid) change(rs(o), mid + 1, r, L, R);
        up(o);
    }
    long long query(int o, int l, int r, int L, int R){
        if(L <= l && r <= R) return tr[o];
        long long res = 0;
        if(L <= mid) res += query(ls(o), l, mid, L, R);
        if(R > mid) res += query(rs(o), mid + 1, r, L, R);
        return res; 
    }
    int main(){
        scanf("%d %d", &n, &m);
        make_d(); build(1, 1, n);
        for(int i = 1, opt, l, r; i <= m; i ++){
            scanf("%d %d %d", &opt, &l, &r);
            if(opt == 1) change(1, 1, n, l, r);
            else printf("%lld
    ", query(1, 1, n, l, r));
        }
        return 0;
    }
    

    完美撒花✿✿ヽ(°▽°)ノ✿

  • 相关阅读:
    JavaEE——SpringMVC(11)--拦截器
    JavaEE——SpringMVC(10)--文件上传 CommonsMultipartResovler
    codeforces 460A Vasya and Socks 解题报告
    hdu 1541 Stars 解题报告
    hdu 1166 敌兵布阵 解题报告
    poj 2771 Guardian of Decency 解题报告
    hdu 1514 Free Candies 解题报告
    poj 3020 Antenna Placement 解题报告
    BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告
    poj 1325 Machine Schedule 解题报告
  • 原文地址:https://www.cnblogs.com/wsdslll/p/13710175.html
Copyright © 2011-2022 走看看