1. 程式人生 > 實用技巧 >CodeForces - 438D(線段樹+剪枝)

CodeForces - 438D(線段樹+剪枝)

1.區間求和 2.區間取模 3.單點修改
線段樹,區間取模加一個剪枝:區間最大值<mod,不修改。其他單點取模

#include <bits/stdc++.h>
using namespace std;
#define debug printf("bug!!!\n");
typedef long long ll;
const int MAXN=1e5+10;
const ll MOD=1e9+7;
ll tree[MAXN*4];
ll lazy[MAXN*4];
ll a[MAXN];
ll tree_max[MAXN*4];
void build(int p,int l,int r){
    if(l==r){
        tree[p]=a[l];
        tree_max[p]=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    tree[p]=tree[p<<1]+tree[p<<1|1];
    tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]);
}
void update(int p,int l,int r,int x,int c){
    if(l==r){
        tree[p]=c;
        tree_max[p]=c;
        return;
    }
    int mid=(l+r)>>1;
    if(x<=mid)update(p<<1,l,mid,x,c);
    if(x>mid)update(p<<1|1,mid+1,r,x,c);
    tree[p]=tree[p<<1]+tree[p<<1|1];
    tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]);
}

void update_mod(int p,int l,int r,int L,int R,int x){
    if(L<=l && r<=R){
        if(tree_max[p]<x){
            return;
        }
        if(l==r){
        tree[p]%=x;
        tree_max[p]%=x;
        return;
        }
    }
    int mid=(l+r)>>1;
    if(L<=mid)update_mod(p<<1,l,mid,L,R,x);
    if(R>mid)update_mod(p<<1|1,mid+1,r,L,R,x);
    tree[p]=tree[p<<1]+tree[p<<1|1];
    tree_max[p]=max(tree_max[p<<1],tree_max[p<<1|1]);
}
ll query(int p,int l,int r,int L,int R){
    if(L<=l && r<=R){
        return tree[p];
    }
    int mid=(l+r)>>1;
    ll res=0;
    if(L<=mid)res+=query(p<<1,l,mid,L,R);
    if(R>mid)res+=query(p<<1|1,mid+1,r,L,R);
    return res;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    while(m--){
        int op;
        cin>>op;
        if(op==1){
            int l,r;
            cin>>l>>r;
            cout<<query(1,1,n,l,r)<<endl;
        }
        else if(op==2){
            int l,r,x;
            cin>>l>>r>>x;
            update_mod(1,1,n,l,r,x);
        }
        else{
            int x,c;
            cin>>x>>c;
            update(1,1,n,x,c);
        }
    }


    return 0;
}