通不过样例的线段树模板求调(一年没碰变废物了呜呜)
查看原帖
通不过样例的线段树模板求调(一年没碰变废物了呜呜)
335552
Christophe_楼主2023/7/5 20:24
// Problem: P3372 【模板】线段树 1
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3372
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;

#define int long long 

inline int read(){
    int ret=0,f=1; 
	char ch=getchar();
    while(ch<'0'||ch>'9'){ if(ch=='-') f=-f; ch=getchar(); }
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
inline void write(int x){        
    if(x<0){ putchar('-'); x=-x; }      
    if(x>9) write(x/10);     
    putchar(x%10+'0');     
}

const int MAXN=1e6+7,minL=1,maxR=1e6+7;

int id=0;

struct Node{
	int ls,rs;
	int val,tag;
}tr[MAXN<<2];

void push_up(int p){
	tr[p].val=tr[tr[p].ls].val+tr[tr[p].rs].val;
}

void push_down(int p,int l,int r){
	if(l>=r) return;
	
	int mid=(l+r-1)/2;
	
	if(!tr[p].ls) tr[p].ls=++id;
	if(!tr[p].rs) tr[p].rs=++id;
	
	tr[tr[p].ls].val+=tr[p].tag*(mid-l+1);
	tr[tr[p].ls].tag+=tr[p].tag;
	
	tr[tr[p].rs].val+=tr[p].tag*(r-mid);
	tr[tr[p].rs].tag+=tr[p].tag;
	
	tr[p].tag=0;
}

void add(int l,int r,int x,int p=1,int cl=minL,int cr=maxR){
	if(l==cl&&r==cr){
		tr[p].val+=x*(cr-cl+1);
		tr[p].tag+=x;
		return;
	}
	int mid=(cl+cr-1)/2;
	push_down(p,cl,cr);
	if(r<=mid) add(l,r,x,tr[p].ls,cl,mid);
	else if(l>mid) add(l,r,x,tr[p].rs,mid+1,cr);
	else{
		add(l,mid,x,tr[p].ls,cl,mid);
		add(mid+1,r,x,tr[p].rs,mid+1,cr);
	}
	push_up(p);
}

int qry(int l,int r,int p=1,int cl=minL,int cr=maxR){
	if(l==cl&&r==cr) return tr[p].val;	
	int mid=(cl+cr-1)/2;
	push_down(p,cl,cr);
	if(r<=mid) return qry(l,r,tr[p].ls,cl,mid);
	else if(l>mid) return qry(l,r,tr[p].rs,mid+1,cr);
	else{
		int lans=qry(l,mid,tr[p].ls,cl,mid);
		int rans=qry(mid+1,r,tr[p].rs,mid+1,cr);
		return lans+rans;
	}
}

int n,m;

signed main(){
	n=read(),m=read();
	
	for(int i=1;i<=n;++i){
		int tmp=read();
		add(i,i,tmp);
	}	
	
	for(int i=1;i<=m;++i){
		int op=read(),x=read(),y=read();
		if(op==1){
			int k=read();
			add(x,y,k);
		}else{
			write(qry(x,y));
			putchar('\n');
		}
	}
	
	return 0;
}

动态开点线段树,拆区间写法,瞪了半天不知道哪里错了(

2023/7/5 20:24
加载中...