• Codeforces 920F


    <题目链接>

    题目大意:

    给你一个序列,有两个操作,一个是求区间 l - r 的和,另一个是对区间l-r的元素修改值,x=d(x),d(x)为x的因子个数。

    解题分析:

    因为可能有多次修改操作,并且修改的范围可能比较大,所以提前将1~1e6范围内的数的因子个数全部打表进行处理。但是仅仅这样还是不行的,因为如果每次区间更新都暴力更新到叶子节点的话,区间更新 $O(nlog(n))$ ,然后m次询问,时间复杂度就达到了$O(n*mlog(n))$,而本题n给到了3e5,毫无疑问这样暴力更新是会超时的。我们发现1、2的因子数为它们本身,所以在更新的过程中,如果该区间都为1或2,就不用继续向下进行更新。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N int(3e5+7)
     5 #define Max int(1e6+7)
     6 #define lson rt<<1,l,mid
     7 #define rson rt<<1|1,mid+1,r
     8 #define clr(a,b) memset(a,b,sizeof(a))
     9 #define rep(i,s,t) for(int i=s;i<=t;i++)
    10 typedef long long ll;
    11 int n,q;
    12 int arr[N],facnum[Max+100];
    13 ll flag[N<<2],tr[N<<2];
    14 
    15 template<typename T>
    16 inline T read(T&x){
    17     x=0;int f=0;char ch=getchar();
    18     while(ch<'0'||ch>'9')f|=(ch=='-'),ch=getchar();
    19     while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();
    20     return x=f?-x:x;
    21 }
    22 int Getfac(int x){     //得到该数的所有因子数
    23     int sum=1,cnt;
    24     for(int i=2;i*i<=x;i++){
    25         cnt=0;
    26         while(x%i==0)x/=i,cnt++;
    27         sum*=(cnt+1);
    28     }
    29     if(x>1) sum*=2;
    30     return sum;
    31 }
    32 void Pushup(int rt){
    33     tr[rt]=tr[rt<<1]+tr[rt<<1|1];
    34     if(!flag[rt<<1]&&!flag[rt<<1|1])flag[rt]=0;     //如果两个子区间都不需要修改,说明这个区间不需要再进行修改
    35 }
    36 void build(int rt,int l,int r){
    37     flag[rt]=1;
    38     if(l==r){
    39         tr[rt]=arr[l];return;
    40     }
    41     int mid=(l+r)>>1;
    42     build(lson);build(rson);
    43     Pushup(rt);
    44 }
    45 void update(int rt,int l,int r,int L,int R){      //区间更新,维护一个区间标记,记录该区间是否需要改变
    46     if(L<=l&&r<=R&&!flag[rt])return;     //如果这部分区间不需要修改,直接返回
    47     if(l==r){
    48         tr[rt]=facnum[tr[rt]];     //进行单点修改
    49         if(tr[rt]==1||tr[rt]==2)flag[rt]=0;     //如果该点为1或2,那么该点就不用再修改了,因为1、2的因子个数仍然为1、2
    50         return;
    51     }
    52     int mid=(l+r)>>1;
    53     if(L<=mid&&flag[rt<<1])update(lson,L,R);
    54     if(R>mid&&flag[rt<<1|1])update(rson,L,R);
    55     Pushup(rt);
    56 }
    57 ll query(int rt,int l,int r,int L,int R){       //区间查询
    58     if(L<=l&&r<=R)return tr[rt];
    59     ll ans=0;
    60     int mid=(l+r)>>1;
    61     if(L<=mid)ans+=query(lson,L,R);
    62     if(R>mid)ans+=query(rson,L,R);
    63     return ans;
    64 }    
    65 int main(){
    66     for(int i=1;i<=Max;i++)facnum[i]=Getfac(i);    //打表预处理得到1~1e6中所有的数的因子个数
    67     read(n);read(q);
    68     rep(i,1,n)read(arr[i]);
    69     build(1,1,n);
    70     while(q--){
    71         int op,x,y;
    72         read(op);read(x);read(y);
    73         if(op==1)update(1,1,n,x,y);
    74         else printf("%lld
    ",query(1,1,n,x,y));
    75     }
    76 }

    2019-02-16

  • 相关阅读:
    Vue生命周期
    脚本生命周期
    音频
    光照系统
    InstantOC(对象渲染---游戏优化)
    kafka单机环境配置以及基本操作
    mysql 锁机制
    java.math.BigDecimal类multiply的使用
    去掉返回的json中特殊字符
    TheadLocal与synchronized
  • 原文地址:https://www.cnblogs.com/00isok/p/10389286.html
Copyright © 2020-2023  润新知