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

        Dicription

    Let D(x) be the number of positive divisors of a positive integer x. For example, D(2) = 2 (2 is divisible by 1 and 2), D(6) = 4 (6 is divisible by 1, 2, 3 and 6).

    You are given an array a of n integers. You have to process two types of queries:

    1. REPLACE l r — for every  replace ai with D(ai);
    2. SUM l r — calculate .

    Print the answer for each SUM query.

    Input

    The first line contains two integers n and m (1 ≤ n, m ≤ 3·105) — the number of elements in the array and the number of queries to process, respectively.

    The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 106) — the elements of the array.

    Then m lines follow, each containing 3 integers tiliri denoting i-th query. If ti = 1, then i-th query is REPLACE li ri, otherwise it's SUM li ri (1 ≤ ti ≤ 2, 1 ≤ li ≤ ri ≤ n).

    There is at least one SUM query.

    Output

    For each SUM query print the answer to it.

    Example
    Input
    7 6
    6 4 1 10 3 2 4
    2 1 7
    2 4 5
    1 3 5
    2 4 4
    1 5 7
    2 1 7
    Output
    30
    13
    4
    22

    可以发现每个数被改若干次之后就会变成2(或者这个数本来就为1它也只能是1),而这个次数的最大值也不会很大,所以我们就可以维护一个还没有变成≤2的位置集合,然后暴力单点修改。又因为是求前缀和,所以我们再维护一个树状数组就好了,时间复杂度O(N*log²N)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #define ll long long
    #define maxn 300005
    #define maxm 1000000
    using namespace std;
    set<int> s;
    set<int> ::iterator it;
    int zs[maxn],t=0,low[maxm+5];
    int d[maxm+5],n,m,le,ri,opt;
    bool v[maxm+5];
    int a[maxn];
    ll f[maxn],qz[maxn];
    
    inline void init(){
        d[1]=1,low[1]=1;
        for(int i=2;i<=maxm;i++){
            if(!v[i]) zs[++t]=i,d[i]=2,low[i]=i;
            for(int j=1,u;j<=t&&(u=zs[j]*i)<=maxm;j++){
                v[u]=1;
                if(!(i%zs[j])){
                    low[u]=low[i]*zs[j];
                    if(low[i]==i) d[u]=d[i]+1;
                    else d[u]=d[low[u]]*d[i/low[i]];
                    break;
                }
                low[u]=zs[j],d[u]=d[i]<<1;
            }
        }
        
    }
    
    inline void update(int x,int y){
        for(;x<=n;x+=x&-x) f[x]+=(ll)y;
    }
    
    inline ll query(ll x){
        ll an=0;
        for(;x;x-=x&-x) an+=f[x];
        return an;
    }
    
    inline void solve(){
        int pre=*s.lower_bound(le);
        while(pre<=ri){
            update(pre,d[a[pre]]-a[pre]);
            a[pre]=d[a[pre]];
            if(a[pre]<=2) s.erase(pre);
            pre=*s.upper_bound(pre);
        }
    }
    
    int main(){
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",a+i);
            qz[i]=qz[i-1]+(ll)a[i];
            s.insert(i);
        }
        s.insert(n+1);
        
        while(m--){
            scanf("%d%d%d",&opt,&le,&ri);
            if(opt==2) printf("%lld
    ",qz[ri]-qz[le-1]+query(ri)-query(le-1));
            else solve();
        }
        
        return 0;
    }
    

      

  • 相关阅读:
    Codeforces Round #590 D. Distinct Characters Queries
    线段树模板加模板题POJ3468
    hihoCoder挑战赛5 C 与链
    HDU 5044 Tree 树链剖分
    HYSBZ 1901 Dynamic Rankings 树状数组套主席树
    POJ 2761 Feed the dogs 主席树
    POJ 2104 K-th Number 主席树 区间第K大
    HDU 4547 CD操作 LCA
    POJ 1470 Closest Common Ancestors 离线LCA
    HYSBZ 1036 树的统计Count 树链剖分 线段树
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8410775.html
Copyright © 2011-2022 走看看