线段树简单题集

【线段树】CodeForces - 438D The Child and Sequence (区间取模)

题目大意:
有三种操作:1.进行区间求和  2.进行区间取模  3.进行单点更新

解题分析:
主要是考虑区间取模操作如何处理,不可能每次取模都对所有的数暴力取模一次,有一种很常见的剪枝就是,维护区间最大值,只有当最大值大于模数的时候,才向下继续进行取模操作,否则终止。因为有一个很显然的结论,对于每个能够取模的数,取模之后,它必然会变成小于等于它的$\frac {1}{2}$的数。所以每个数最多会被模$log$次,所以区间取模的复杂度为$O(nlogn)$。

#include <bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T&x){        
    x=0;int f=1;char ch=getchar();
    while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); }
    while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
    x*=f;
}
#define Lson rt<<1,l,mid
#define Rson rt<<1|1,mid+1,r
#define ll long long 
#define REP(i,s,t) for(int i=s;i<=t;i++)

const int N = 1e5+5;
ll mx[N<<2],sum[N<<2],a[N];
int n,m;

inline void Pushup(int rt){
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int rt,int l,int r){
    if(l==r){
        mx[rt]=sum[rt]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(Lson);build(Rson);
    Pushup(rt);
}
void up1(int rt,int l,int r,int loc,int val){              //单点更新
    if(l==r){ mx[rt]=sum[rt]=val; return; }
    int mid=(l+r)>>1;
    if(loc<=mid)up1(Lson,loc,val);
    else up1(Rson,loc,val);
    Pushup(rt);
}
void up2(int rt,int l,int r,int L,int R,int md){
    if(md>mx[rt])return;
    if(l==r){
        sum[rt]%=md;mx[rt]=sum[rt];
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid)up2(Lson,L,R,md);
    if(R>mid)up2(Rson,L,R,md);
    Pushup(rt);
}
ll query(int rt,int l,int r,int L,int R){
    if(L<=l&&r<=R)return sum[rt];
    int mid=(l+r)>>1;
    ll ans=0;
    if(L<=mid)ans+=query(Lson,L,R);
    if(R>mid)ans+=query(Rson,L,R);
    return ans;
}
int main(){
    read(n);read(m);
    REP(i,1,n)read(a[i]);
    build(1,1,n);
    while(m--){
        int op;read(op);
        if(op==1){
            int l,r;read(l);read(r);
            printf("%lld\n",query(1,1,n,l,r));
        }else if(op==2){
            int l,r,md;read(l);read(r);read(md);
            up2(1,1,n,l,r,md);
        }else{
            int loc,c;read(loc);read(c);
            up1(1,1,n,loc,c);
        }
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/00isok/p/10994865.html
今日推荐