zoukankan      html  css  js  c++  java
  • 2020西工大校赛 G智乃与无意义的题目(线段树)

    这题是单点修改和区间查询,因此想到用线段树求,问题是里面的因子个数的维护

    显然不可能是先算出来再分解因子,因此我们想到唯一分解定理,也就是所有数都是某些质因数的倍数的乘积

    并且每个数不超过10,10里面质数只有2 3 5  7 9,因此只需要维护这些值就行了,因此因数个数就是这个质因数的指数+1的乘积。

    所以在修改的时候对每个数进行分解质因数,因为每个数只有10以内,所以不贡献复杂度

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int mod=998244353;
    int n,m;
    int a[N];
    ll res[10];
    struct node{
        int l,r;
        int s[10];
    }tr[N<<2];
    void build(int u,int l,int r){
        if(l==r){
            tr[u]=node{l,l};
        }
        else{
            tr[u]=node{l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
        }
    }
    void pushup(int u){
        int i;
        for(i=2;i<=9;i++){
            tr[u].s[i]=tr[u<<1].s[i]+tr[u<<1|1].s[i];
        }
    }
    void modify(int u,int l,int x){
        if(tr[u].l==tr[u].r){
            for(int i=2;i<=9;i++)
                tr[u].s[i]=0;
            int i;
            for(i=2;i*i<=x;i++){
                if(x%i==0){
                    while(x%i==0){
                        tr[u].s[i]++;
                        x/=i;
                    }
                }
            }
            if(x>1)
                tr[u].s[x]++;
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,x);
        else
            modify(u<<1|1,l,x);
        pushup(u);
    }
    void query(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            int i;
            for(i=2;i<=9;i++){
                res[i]=(res[i]+tr[u].s[i])%mod;
            }
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            query(u<<1,l,r);
        if(r>mid)
            query(u<<1|1,l,r);
    }
    ll solve(int l,int r){
        memset(res,0,sizeof res);
        int i;
        query(1,l,r);
        ll ans=1;
        for(i=2;i<=9;i++){
            ans=(ans*(res[i]+1))%mod;
        }
        return ans;
    }
    int main(){
        cin>>n>>m;
        int i;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        for(i=1;i<=n;i++){
            modify(1,i,a[i]);
        }
        int op;
        while(m--){
            scanf("%d",&op);
            if(op==1){
                int l,x;
                scanf("%d%d",&l,&x);
                modify(1,l,x);
            }
            else{
               int l,r;
               scanf("%d%d",&l,&r);
               printf("%lld
    ",solve(l,r));
            }
        }
    }
    View Code
  • 相关阅读:
    OpenGL搭建环境-VS2012【OpenGL】
    IOS内存约定-【ios】
    bootstrap下jQuery自动完成的样式调整-【jQuery】
    如何访问https的网站?-【httpclient】
    twitter typeahead控件使用经历
    grails服务端口冲突解决办法-【grails】
    jQuery中live函数的替代-【jQuery】
    如何自动设置网页中meta节点keywords属性-【SEO】
    如何在grails2.3.x中的fork模式下进行调试?-【grails】
    树的简介及Java实现
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12825266.html
Copyright © 2011-2022 走看看