传送门:线段树1
1 #include<cstdio> 2 3 const int MAXN = 200000*4; 4 typedef long long LL; 5 6 int n,m,p,u,v; 7 long long x,Segment_Tree[MAXN],Add[MAXN]; 8 9 template <typename Type> inline void Read(Type &in){ 10 Type f=1;char ch=getchar(); 11 for(;ch>‘9‘||ch<‘0‘;ch=getchar()) if(ch==‘-‘) f=-1; 12 for(in=0;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) in=in*10+ch-‘0‘; 13 in*=f; 14 } 15 16 void Build(int Node,int Left,int Right){ 17 if(Left==Right){ 18 Read(Segment_Tree[Node]); 19 return; 20 } 21 int Mid=(Left+Right)>>1; 22 Build(Node<<1,Left,Mid); 23 Build(Node<<1|1,Mid+1,Right); 24 Segment_Tree[Node]=Segment_Tree[Node<<1]+Segment_Tree[Node<<1|1]; 25 } 26 27 void PushDown(int Node,int Begin,int End){ 28 if(!Add[Node]) return; 29 int Mid=(Begin+End)>>1; 30 Add[Node<<1]+=Add[Node]; 31 Add[Node<<1|1]+=Add[Node]; 32 Segment_Tree[Node<<1]+=(Mid+1-Begin)*Add[Node]; 33 Segment_Tree[Node<<1|1]+=(End-Mid)*Add[Node]; 34 Add[Node]=0; 35 } 36 37 void Change(int Node,int Begin,int End,int Left,int Right,LL Add_Num){ 38 if(Begin>Right||End<Left) return; 39 if(Begin>=Left&&End<=Right){ 40 Segment_Tree[Node]+=(End-Begin+1)*Add_Num; 41 Add[Node]+=Add_Num; 42 } 43 else{ 44 if(Add[Node]) PushDown(Node,Begin,End); 45 int Mid=(Begin+End)>>1; 46 Change(Node<<1,Begin,Mid,Left,Right,Add_Num); 47 Change(Node<<1|1,Mid+1,End,Left,Right,Add_Num); 48 Segment_Tree[Node]=Segment_Tree[Node<<1]+Segment_Tree[Node<<1|1]; 49 } 50 } 51 52 LL Query(int Node,int Begin,int End,int Left,int Right){ 53 if(Begin>Right||End<Left) return 0; 54 if(Begin>=Left&&End<=Right) return Segment_Tree[Node]; 55 if(Add[Node]) PushDown(Node,Begin,End); 56 int Mid=(Begin+End)>>1; 57 return Query(Node<<1,Begin,Mid,Left,Right)+Query(Node<<1|1,Mid+1,End,Left,Right); 58 } 59 60 int main(){ 61 Read(n); 62 Build(1,1,n);Read(m); 63 while(m--){ 64 Read(p);Read(u);Read(v); 65 if(p==1){ 66 Read(x); 67 Change(1,1,n,u,v,x); 68 } 69 else printf("%lld\n",Query(1,1,n,u,v)); 70 } 71 return 0; 72 }
时间: 2024-10-05 18:23:01