ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2020西工大校赛 G智乃与无意义的题目(线段树)

2020-05-04 09:04:18  阅读:227  来源: 互联网

标签:10 int tr ll 西工大 long 2020 校赛 质因数


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

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

并且每个数不超过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\n",solve(l,r));
        }
    }
}
View Code

 

标签:10,int,tr,ll,西工大,long,2020,校赛,质因数
来源: https://www.cnblogs.com/ctyakwf/p/12825266.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有