社区讨论

动态开点线段树但是50pts

P13825【模板】线段树 1.5参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mik0wgjo
此快照首次捕获于
2025/11/29 16:22
3 个月前
此快照最后确认于
2025/11/30 13:20
3 个月前
查看原帖
RE:#6#7#8#9#10
CPP
#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int N=7e6+111;
struct pai{
    int thi,tag,lef,rig;
};
int n,m;
struct tree{
	pai t[N];
    int tot;
    void in_it(int x){
        t[x]={0,0,-1llu,-1llu};
    }
    void _init(){
        tot=1;
        in_it(1);
    }
    int _merge(int a,int b){
        return a+b;
    }
	pai merge(pai a,pai b,pai c){
	    pai ret{_merge(a.thi,b.thi),0,c.lef,c.rig};
	    return ret;
	}
	void push_down(int k,int cl,int cr){
		if(t[k].tag==0){
			return;
		}
        if(t[k].lef==-1){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==-1){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
	    int lc=t[k].lef,rc=t[k].rig;
		int mid=(cl+cr)>>1;
        // cerr<<"|"<<k<<" "<<lc<<" "<<rc<<"|"<<t[k].tag<<" "<<t[lc].thi<<" "<<t[rc].thi<<"\n";
	    t[lc].tag+=t[k].tag;
	    t[rc].tag+=t[k].tag;
	    t[lc].thi+=(mid-cl+1)*t[k].tag;
	    t[rc].thi+=(cr-mid)*t[k].tag;
	    t[k].tag=0;
	}
	int qry(int k,int l,int r,int cl,int cr){
        // cerr<<"||||"<<k<<" "<<t[k].tag<<"\n";
	    if(cl>r||cr<l||l>r){
	        return 0;
	    }
		if(cl>=l&&cr<=r){
            // cerr<<"|"<<k<<"|"<<cl<<" "<<cr<<"\n";
			return t[k].thi;
		}
        if(t[k].lef==-1){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==-1){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
	    int lc=t[k].lef,rc=t[k].rig;
		int mid=(cl+cr)>>1;
	    push_down(k,cl,cr);
		return _merge(qry(lc,l,r,cl,mid),qry(rc,l,r,mid+1,cr));
	}
	void modify(int k,int l,int r,int cl,int cr,int x){
	    if(cl>r||cr<l||l>r){
	        return;
	    }
		if(l<=cl&&r>=cr){
	        t[k].tag+=x;
	        t[k].thi+=x*(cr-cl+1);
            // cerr<<k<<"-|"<<t[k].tag<<" "<<t[k].thi<<"\n";
	        return;
		}
        if(t[k].lef==-1){
            t[k].lef=++tot;
            in_it(t[k].lef);
        }
        if(t[k].rig==-1){
            t[k].rig=++tot;
            in_it(t[k].rig);
        }
	    int lc=t[k].lef,rc=t[k].rig;
		int mid=(cl+cr)>>1;
	    push_down(k,cl,cr);
	    modify(lc,l,r,cl,mid,x);
	    modify(rc,l,r,mid+1,cr,x);
        // cerr<<"|||"<<k<<" "<<t[k].lef<<" "<<t[k].rig<<"\n";
	    t[k]=merge(t[lc],t[rc],t[k]);
	}
}tr;
int a[N];
int t[N];
signed main(){
    scanf("%llu%llu",&n,&m);
    tr._init();
    for(int i=1;i<=n;i++){
        a[i]=i;
        t[i]=t[i-1]+a[i];
    }
    for(int i=1;i<=m;i++){
        int k;
        scanf("%llu",&k);
        if(k==1){
            int x,y,z;
            scanf("%llu%llu%llu",&x,&y,&z);
            tr.modify(1,x,y,1,n,z);
        }else{
            int x,y;
            scanf("%llu%llu",&x,&y);
            printf("%llu\n",tr.qry(1,x,y,1,n)+t[y]-t[x-1]);
        }
        // cerr<<i<<"|";
        // for(int j=1;j<=n;j++){
        //     cerr<<tr.qry(1,j,j,1,n)<<" ";
        // }
        // cerr<<"\n";
    }
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...