Codeforces 438D The Child and Sequence

Posted NINGLONG

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 438D The Child and Sequence相关的知识,希望对你有一定的参考价值。

题意:给定一个n个数的序列,完成以下3个操作:

  1.给定区间求和

  2.给定区间对x取模

  3.单点修改

 

对一个数取模,这个数至少折半。于是我们记一个最大值max,如果x>max则不做处理。

 

#include<stdio.h>
#include<algorithm>
using namespace std;
#define MAXN 1000000+10
typedef long long LL;
struct tree{LL mx,sum;}tr[MAXN<<1];
int n,m;
LL a[MAXN];
void build(int k,int l,int r){
    if(l==r){
        tr[k].mx=tr[k].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
LL sum(int k,int l,int r,int L,int R){
    if(l>=L&&r<=R)return tr[k].sum;    
    int mid=(l+r)>>1;
    if(R<=mid)return sum(k<<1,l,mid,L,R);
    else if(L>mid)return sum(k<<1|1,mid+1,r,L,R);
    else return sum(k<<1,l,mid,L,R)+sum(k<<1|1,mid+1,r,L,R);
    tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void update(int k,int l,int r,int t,LL x){
    if(l==t&&r==t){
        tr[k].mx=tr[k].sum=x;
        return;
    }
    int mid=(l+r)>>1;
    if(t<=mid)update(k<<1,l,mid,t,x);
    if(t>mid)update(k<<1|1,mid+1,r,t,x);
    tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void mod(int k,int l,int r,int L,int R,LL x){
    if(tr[k].mx<x)return;
    if(l==r){
        tr[k].mx%=x;
        tr[k].sum%=x;
        return;
    }
    int mid=(l+r)>>1;
    if(R<=mid)mod(k<<1,l,mid,L,R,x);
    else if(L>mid)mod(k<<1|1,mid+1,r,L,R,x);
    else mod(k<<1,l,mid,L,R,x),mod(k<<1|1,mid+1,r,L,R,x);
    tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
int main(){
    //freopen("mod.in","r",stdin);
    //freopen("mod.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
    build(1,1,n);
    while(m--){
        int opt;
        scanf("%d",&opt);
        if(opt==1){
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%I64d\n",sum(1,1,n,l,r));
        }
        if(opt==2){
            int l,r;LL x;
            scanf("%d%d%I64d",&l,&r,&x);
            mod(1,1,n,l,r,x);
        }
        if(opt==3){
            int k;LL y;
            scanf("%d%I64d",&k,&y);
            update(1,1,n,k,y);
        }
    }
    return 0;
}

 

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

codeforces438D The Child and Sequence

438D - The Child and Sequence

CF438D The Child and Sequence

CF(438D) The Child and Sequence(线段树)

CF438D The Child and Sequence 线段树

CF438D The Child and Sequence(线段树)