CF438D The Child and Sequence 线段树

Posted guangheli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; 
}

  

以上是关于CF438D The Child and Sequence 线段树的主要内容,如果未能解决你的问题,请参考以下文章

CF438D The Child and Sequence 线段树

CF438D The Child and Sequence(线段树)

CF438D The Child and Sequence

CF438D The Child and Sequence

CF438D The Child and Sequence 线段树

codeforces438D The Child and Sequence