• CF920F SUM and REPLACE(线段树+思维)


    这题比较套路,首先我们发现,区间变成约数个数是不可能用区间维护的,因此这题显然有个trick

    既然只能暴力修改单点,但是我们又要要求修改次数不能太多,因此可以联想到,是不是我约数个数求几次就变成一个常数了

    继续观察,果然是这样,因此我们发现修改次数不会太多

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    const int mod=1e9+7;
    int a[N];
    struct node{
        int l,r;
        int cnt;
        ll sum;
    }tr[N<<2];
    bool mark[N];
    int prim[N],d[N],num[N];
    int cnt;
    void initial(){
        cnt=0;
        d[1]=1;
        for (int i=2;i<N;++i){
            if (!mark[i]){
                prim[cnt++]=i;
                num[i]=1;
                d[i]=2;
            }
            for (int j=0;j<cnt&&i*prim[j]<N;++j){
                mark[i*prim[j]]=1;
                if (!(i%prim[j])){
                    num[i*prim[j]]=num[i]+1;
                    d[i*prim[j]]=d[i]/(num[i]+1)*(num[i*prim[j]]+1);
                    break;
                }
                d[i*prim[j]]=d[i]*d[prim[j]];
                num[i*prim[j]]=1;
            }
        }
    }
    void pushup(int u){
        tr[u].cnt=tr[u<<1].cnt+tr[u<<1|1].cnt;
        tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r,a[l]==1,a[l]};
        }
        else{
            tr[u]={l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void modify(int u,int l,int r){
        ll x=tr[u].r-tr[u].l+1-tr[u].cnt;
        if(tr[u].sum-tr[u].cnt==x*2)
            return ;
        if(tr[u].l==tr[u].r){
            tr[u].sum=d[tr[u].sum];
            tr[u].cnt=(tr[u].sum==1)?1:0;
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r);
        if(r>mid)
            modify(u<<1|1,l,r);
        pushup(u);
    }
    ll query(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].sum;
        }
        int mid=tr[u].l+tr[u].r>>1;
        ll ans=0;
        if(l<=mid)
            ans+=query(u<<1,l,r);
        if(r>mid)
            ans+=query(u<<1|1,l,r);
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i;
        initial();
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        build(1,1,n);
        while(m--){
            int opt;
            cin>>opt;
            int l,r;
            cin>>l>>r;
            if(opt==1){
                modify(1,l,r);
            }
            else{
                cout<<query(1,l,r)<<endl;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Flipping with Physis: Motion Editing for Acrobatics
    Practicle Character Physics For Animators
    html5 files属性
    ASP.NET大文件上传设置。maxRequestLength无效的情况
    elasticsearch
    html用Css来关闭sougou输入框
    模拟form提交
    疯狂的跨域技术
    日志记录用NLog
    备份iis站点信息
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14097102.html
Copyright © 2020-2023  润新知