平衡树求助
查看原帖
平衡树求助
455558
Imiya楼主2022/8/2 15:01

只过了一个点qwq

#include<iostream>
#include<cstdlib>
using namespace std;
#define int long long
const int N=100100;
int ls[N],rs[N],laz[N],sum[N],pos[N],wei[N],siz[N];
int n,m,a[N];
int cnt;
inline int New(int k){
    cnt++;
    ls[cnt]=rs[cnt]=laz[cnt]=sum[cnt]=0;
    pos[cnt]=k;
    wei[cnt]=random();
    siz[cnt]=1;
    return cnt;
}
inline void push_down(int nd){
    sum[nd]+=laz[nd]*siz[nd];
    a[pos[nd]]+=laz[nd];
    laz[ls[nd]]+=laz[nd];
    laz[rs[nd]]+=laz[nd];
    laz[nd]=0;
}
inline void push_up(int nd){
    sum[nd]=sum[ls[nd]]+sum[rs[nd]]+a[pos[nd]];
    siz[nd]=1+siz[ls[nd]]+siz[rs[nd]];
}
#define p1 first
#define p2 second
pair<int,int>split(int nd,int k){
    if(!nd)return{0,0};
    push_down(nd);
    if(pos[nd]<=k){
        pair<int,int>o=split(rs[nd],k);
        rs[nd]=o.p1;
        push_up(nd);
        return{nd,o.p2};
    }
    else{
        pair<int,int>o=split(ls[nd],k);
        ls[nd]=o.p2;
        push_up(nd);
        return{o.p1,nd};
    }
}
int merge(int u,int v){
    if(!u||!v)return u|v;
    push_down(u);
    push_down(v);
    if(wei[u]<wei[v]){
        rs[u]=merge(rs[u],v);
        push_up(u);
        return u;
    }
    else{
        ls[v]=merge(u,ls[v]);
        push_up(v);
        return v;
    }
}
int rt;
inline void insert(int k){
    pair<int,int>o=split(rt,k);
    rt=merge(o.p1,merge(New(k),o.p2));
}
inline int read(){
    int i=getchar(),r=0,s=1;
    while(i<'0'||i>'9'){if(i=='-')s=-1;i=getchar();}
    while(i>='0'&&i<='9')r=(r<<1)+(r<<3)+(i^48),i=getchar();
    return r*s;
}
inline int get_sum(int l,int r){
    pair<int,int>o=split(rt,l-1);
    pair<int,int>p=split(o.p2,r);
    int res=sum[p.p1];
    rt=merge(o.p1,merge(p.p1,p.p2));
    return res;
}
inline void add(int l,int r,int k){
    pair<int,int>o=split(rt,l-1);
    pair<int,int>p=split(o.p2,r);
    laz[p.p1]+=k;
    rt=merge(o.p1,merge(p.p1,p.p2));
}
signed main(){
//    freopen("read.in","r",stdin);
    cin>>n>>m;
    for(int i=1;i<=n;i++)a[i]=read(),insert(i);
    while(m--){
        int cmd=read(),l=read(),r=read();
        if(cmd==2)printf("%lld\n",get_sum(l,r));
        else add(l,r,read());
    }
    return 0;
}
2022/8/2 15:01
加载中...