模板 線段樹 1

2021-09-25 09:02:13 字數 1923 閱讀 1603

題目描述

如題,已知乙個數列,你需要進行下面兩種操作:

1.將某區間每乙個數加上x

2.求出某區間每乙個數的和

輸入格式

第一行包含兩個整數n、m,分別表示該數列數字的個數和操作的總個數。

第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。

接下來m行每行包含3或4個整數,表示乙個操作,具體如下:

操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k

操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和

輸出格式

輸出包含若干行整數,即為所有操作2的結果。

輸入輸出樣例

輸入 #1複製

5 51 5 4 2 3

2 2 4

1 2 3 2

2 3 4

1 1 5 1

2 1 4

輸出 #1複製118

20說明/提示

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=8,m<=10

對於70%的資料:n<=1000,m<=10000

對於100%的資料:n<=100000,m<=100000

(資料已經過加強_,保證在int64/long long資料範圍內)

樣例說明:

#include#includeusing namespace std;

long long read()

while(ch>='0'&&ch<='9')

return a*x;

}long long n,m,k,x,y,v;

long long a[100001],sum[400001],lazy[400001];

void build(long long node,long long l,long long r)

long long mid=(l+r)>>1;

build(node*2,l,mid);

build(node*2+1,mid+1,r);

sum[node]=sum[node*2]+sum[node*2+1];

}void pushdown(long long node,long long l,long long r)

long long mid=(l+r)>>1;

lazy[node*2]+=lazy[node];

lazy[node*2+1]+=lazy[node];

sum[node*2]+=lazy[node]*(mid-l+1);

sum[node*2+1]+=lazy[node]*(r-mid);

lazy[node]=0;

}void add(long long node,long long l,long long r,long long x,long long y,long long k)

pushdown(node,l,r);

long long mid=(l+r)>>1;

if(x<=mid)

if(y>mid)

sum[node]=sum[node*2]+sum[node*2+1];

}long long ask(long long node,long long l,long long r,long long x,long long y)

pushdown(node,l,r);

long long mid=(l+r)>>1;

long long rnt=0;

if(x<=mid)

if(y>mid)

return rnt;

}int main()

build(1,1,n);

for(int i=1;i<=m;i++)

else

}return 0;

}

模板 線段樹 1

區間修改 區間查詢 include define ll long long using namespace std ll a 100003 原數列 tree 400003 線段樹 delta 400003 標記 void update int now update多多益善 void build in...

線段樹模板(1)

本篇只對線段樹的基本應用介紹 即整區間單次改變,區間求和,單點改變和區間改變乙個道理,只把區間變成點。剩下的線段樹知識點類似 區間求逆序對,區間多次改變 同時 再 或者 或者 區間 合併,交 區間過大在改變時對p取模等放在後面學習給出。若只是需要求區間和或者單點改變,樹狀陣列是個好的選擇,但是其他的...

模板 線段樹1

洛谷p3374 線段樹的結構與樹狀陣列相似,但線段樹更加通用,維護的資料只要滿足區間加即可。線段樹是一棵二叉樹,每個節點表示乙個區間。假設某個節點表示 l,r mid l r 2,則它的左子節點表示 l,mid 右子節點表示 mid 1,r 若乙個節點的編號為x,則它的左子節點編號為x 2,右子節點...