zoukankan      html  css  js  c++  java
  • [Codeforces 920F] SUM and REPLACE

    [题目链接]

             https://codeforces.com/contest/920/problem/F

    [算法]

            显然 , 一个10 ^ 6以内的数在经过最多6次操作后就会变为1或2 , 这是因为一个数的因子个数是根号级别的

            用筛法预处理10 ^ 6以内每个数的因数个数 , 用线段树维护即可 , 修改时可以暴力地修改到叶子节点

            时间复杂度 : O(NlogN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 3e5 + 10;
    const int MAXP = 1e6 + 10;
    typedef long long ll;
    typedef long double ld;
    
    int n , m;
    int val[MAXN] , p[MAXP];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    struct Segment_Tree
    {
            struct Node
            {
                    int l ,r;
                    ll cnt;
                    bool flg;        
            }    a[MAXN << 2];
            inline void build(int index , int l , int r)
            {
                    a[index].l = l , a[index].r = r;
                    if (l == r)
                    {
                            a[index].cnt = val[l];
                            a[index].flg = (a[index].cnt == 1 || a[index].cnt == 2);
                            return;
                    }
                    int mid = (l + r) >> 1;
                    build(index << 1 , l , mid);
                    build(index << 1 | 1 , mid + 1 , r);
                    update(index);
            }
            inline bool update(int index)
            {
                    a[index].flg = a[index << 1].flg & a[index << 1 | 1].flg;
                    a[index].cnt = a[index << 1].cnt + a[index << 1 | 1].cnt;
            }
            inline void modify(int index , int l , int r)
            {
                    int mid =(a[index].l + a[index].r) >> 1;
                    if (a[index].flg) return;
                    if (a[index].l == l && a[index].r == r)
                    {
                            if (l == r) 
                            {
                                    a[index].cnt = p[a[index].cnt];
                                    a[index].flg = (a[index].cnt == 1 || a[index].cnt == 2);
                                    return;
                            } else
                            {
                                    modify(index << 1 , l , mid);
                                    modify(index << 1 | 1 , mid + 1 , r);
                                    update(index); 
                            }
                            return;
                    }
                    if (mid >= r) modify(index << 1 , l , r);
                    else if (mid + 1 <= l) modify(index << 1 | 1 , l , r);
                    else
                    {
                            modify(index << 1 , l , mid);
                            modify(index << 1 | 1 , mid + 1 , r);
                    }
                    update(index);
            }
            inline ll query(int index , int l , int r)
            {
                    if (a[index].l == l && a[index].r == r)
                            return a[index].cnt;
                    else
                    {
                            int mid = (a[index].l + a[index].r) >> 1;
                            if (mid >= r) return query(index << 1 , l , r);
                            else if (mid + 1 <= l) return query(index << 1 | 1 , l , r);
                            else return query(index << 1 , l , mid) + query(index << 1 | 1 , mid + 1 , r);
                    }
            }
    } SGT;
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i < MAXP; i++)
            {
                    for (int j = i; j < MAXP; j += i)
                            ++p[j];        
            } 
            for (int i = 1; i <= n; i++) read(val[i]);
            SGT.build(1 , 1 , n);
            for (int i = 1; i <= m; i++)
            {
                    int type;
                    read(type);
                    if (type == 1)
                    {
                            int l , r;
                            read(l); read(r);
                            SGT.modify(1 , l , r);        
                    }    else
                    {
                            int l , r;
                            read(l); read(r);
                            printf("%lld
    " , SGT.query(1 , l , r));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    简单测试
    纸玫瑰
    Java 字符串编码 (保存成txt测试)
    创建 Filter
    jee中文名图片+tomcat ==> 中文乱码的另类处理(未成功)
    dom4j_01_02
    dom4j_01_01
    Java 字符串编码
    websocket

  • 原文地址:https://www.cnblogs.com/evenbao/p/10089691.html
Copyright © 2011-2022 走看看