• CF438D The Child and Sequence 线段树


    你发现每一次有意义的取模至少会把一个数减半. 

    所以如果没有赋值操作,每个数最多减半 $log$ 次,复杂度就是 $O(nlog^2n)$ 的. 

    现在考虑赋值:依次最多只会增加 $O(logn)$ 的时间复杂度,所以复杂度还是 $O(nlog^2n)$ 的. 

    code: 

    #include <bits/stdc++.h> 
    #define N 100005  
    #define inf 12 
    #define ll long long  
    #define lson now<<1
    #define rson now<<1|1 
    #define setIO(s) freopen(s".in","r",stdin)    
    using namespace std;
    ll A[N],mx[N<<2];
    ll sum[N<<2];  
    void pushup(int l,int r,int now) 
    {
        int mid=(l+r)>>1; 
        mx[now]=-inf, sum[now]=0; 
        if(l<=mid) sum[now]+=sum[lson], mx[now]=max(mx[now], mx[lson]); 
        if(r>mid)  sum[now]+=sum[rson], mx[now]=max(mx[now], mx[rson]);   
    }
    void build(int l,int r,int now) 
    {
        if(l==r) 
        {
            sum[now]=mx[now]=A[l]; 
            return; 
        } 
        int mid=(l+r)>>1;    
        if(l<=mid) build(l,mid,lson); 
        if(r>mid)  build(mid+1,r,rson);  
        pushup(l,r,now); 
    }   
    ll query(int l,int r,int now,int L,int R) 
    {
        if(l>=L&&r<=R) return sum[now];  
        ll tmp=0; 
        int mid=(l+r)>>1;  
        if(L<=mid) tmp+=query(l,mid,lson,L,R); 
        if(R>mid)  tmp+=query(mid+1,r,rson,L,R); 
        return tmp;     
    }   
    void update(int l,int r,int now,int L,int R,int mod) 
    {
        if(mx[now]<mod) return;    
        if(l==r) 
        {
            sum[now]%=mod;                         
            mx[now]%=mod; 
            return; 
        } 
        int mid=(l+r)>>1;   
        if(L<=mid) update(l,mid,lson,L,R,mod); 
        if(R>mid)  update(mid+1,r,rson,L,R,mod); 
        pushup(l,r,now);      
    }
    void modify(int l,int r,int now,int p,int v) 
    {
        if(l==r) 
        {
            sum[now]=mx[now]=1ll*v; 
            return; 
        } 
        int mid=(l+r)>>1; 
        if(p<=mid) modify(l,mid,lson,p,v); 
        else modify(mid+1,r,rson,p,v); 
        pushup(l,r,now);    
    }
    int main() 
    {
        int i,j,n,m; 
        // setIO("input");    
        scanf("%d%d",&n,&m); 
        for(i=1;i<=n;++i) scanf("%lld",&A[i]);           
        build(1,n,1);    
        for(i=1;i<=m;++i) 
        {
            int op,l,r,x; 
            scanf("%d",&op);         
            if(op==1) 
            {
                scanf("%d%d",&l,&r); 
                printf("%lld
    ",query(1,n,1,l,r)); 
            } 
            if(op==2) 
            {
                scanf("%d%d%d",&l,&r,&x);   
                update(1,n,1,l,r,x); 
            }  
            if(op==3) 
            {
                scanf("%d%d",&l,&x); 
                modify(1,n,1,l,x); 
            }
        }
        return 0; 
    }
    

      

  • 相关阅读:
    poj 3253超时
    poj 3617输出格式问题
    dfs的返回条件
    hdu1010感想
    2018.7.19训练赛总结
    2018.7.12训练赛 -G
    汇编实验16 编写包含多个功能子程序的中断例程——浅谈直接地址表
    新的一年来了,先看一看自己的编程能力吧!
    汇编实验15:安装新的int 9中断例程
    汇编实验14:访问CMOS RAM
  • 原文地址:https://www.cnblogs.com/guangheli/p/11613862.html
Copyright © 2020-2023  润新知