线段树求调
查看原帖
线段树求调
692647
tanghg楼主2022/9/2 17:59

rt,输入所有数字后还要输入,并且输出的也不对。

#include<cstdio>
using namespace std;
typedef long long ll;
const ll MAXN=1e5;
ll w[MAXN*4],a[MAXN],n,q;
ll ls(ll u){return u<<1;}
ll rs(ll u){return u<<1|1;}
void push_back(const ll u){
    w[u]=w[u*2]+w[u*2+1];
}
void build(const ll u,ll l,ll r){
    if(l==r){
        w[u]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(ls(u),l,mid);
    build(rs(u),mid+1,r);
    push_back(u);
};
bool In(ll L,ll R,ll l,ll r,bool t){return t?((L<=l)&&(r<=R)):((L>r)||(R<l));}
ll lazy_tag[MAXN*4];
void make_tag(ll u,ll len,ll x){
    lazy_tag[u]+=x;
    w[u]+=len*x;
}
void push_down(ll u,ll l,ll r){
    ll mid=(l+r)>>1;
    make_tag(ls(u),mid-l+1,lazy_tag[u]);
    make_tag(rs(u),r-mid,lazy_tag[u]);
    lazy_tag[u]=0;
}
ll find(ll u,ll L,ll R,ll l,ll r,ll mod=-1){
    if(In(L,R,l,r, true)){
        if(mod==-1){
            return w[u];
        }else{
            return w[u]%mod;
        }
    }else if(!In(L,R,l,r, false)){
        ll mid=(L+r)>>1;
        push_down(u,l,r);
        return find(ls(u),L,mid,l,r)+ find(rs(u),mid+1,R,l,r);
    }else{return 0;}
}
void update(ll u,ll L,ll R,ll l,ll r,ll x){
    if(In(L,R,l,r, true)){
        make_tag(u,R-L+1,x);
    }else if(!In(L,R,l,r, false)){
        ll mid=(l+r)>>1;
        push_down(u,L,R);
        update(ls(u),L,mid,l,r,x);
        update(rs(u), mid+1,R,l,r,x);
        push_back(u);
    }
}
int main(){
    scanf("%lld%lld",&n,&q);
    for (int i = 1; i <=n ; ++i) {
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    for (int i = 1; i <=q ; ++i) {
        int op,x,y;ll k;
        scanf("%lld",&op);
        if(op==1){
            scanf("%d%d%lld",&x,&y,&k);
            update(1,1,n,x,y,k);
        }else{
            scanf("%d%d",&x,&y);
            printf("%lld\n", find(1,1,n,x,y));
        }
    }
    return 0;
}
2022/9/2 17:59
加载中...