码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 438D The Child and Sequence

时间:2017-10-01 23:00:25      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:blog   type   return   tree   long   style   for   else   stdin   

题意:给定一个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

标签:blog   type   return   tree   long   style   for   else   stdin   

原文地址:http://www.cnblogs.com/NINGLONG/p/7618017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!