線段樹的區間加法與區間乘法

2021-10-05 05:19:37 字數 3245 閱讀 9738

題目描述

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

將某區間每乙個數加上 kk。

求出某區間每乙個數的和。

輸入格式

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

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

接下來 mm 行每行包含 33 或 44 個整數,表示乙個操作,具體如下:

1 x y k:將區間 [x, y][x,y] 內每個數加上 kk。

2 x y:輸出區間 [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

#include

#include

#include

using

namespace std;

typedef

long

long ll;

struct nodetree[

4000010];

ll a[

4000010];

void

build

(int l,

int r,

int now)

int mid=

(l+r)

>>1;

build

(l,mid,now*2)

;build

(mid+

1,r,now*2+

1); tree[now]

.data=tree[now*2]

.data+tree[now*2+

1].data;

}void

pushdown

(int x)

}//update三種情況:1.區間完全被包含 2.左兒子區間部分包含 3.右兒子區間部分包含

void

update

(int l,

int r,

int now,

int k)

pushdown

(now);if

(tree[now*2]

.r>=l)

update

(l,r,now*

2,k);if

(tree[now*2+

1].l<=r)

update

(l,r,now*2+

1,k)

; tree[now]

.data=tree[now*2]

.data+tree[now*2+

1].data;

}ll get_sum

(int l,

int r,

int now)

pushdown

(now)

; ll ans=0;

if(tree[now*2]

.r>=l)ans=ans+

get_sum

(l,r,now*2)

;if(tree[now*2+

1].l<=r)ans=ans+

get_sum

(l,r,now*2+

1);return ans;

}int

main()

else

}return0;

}

題目描述

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

將某區間每乙個數乘上 xx

將某區間每乙個數加上 xx

求出某區間每乙個數的和

輸入格式

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

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

接下來 mm 行每行包含若干個整數,表示乙個操作,具體如下:

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

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

操作 33: 格式:3 x y 含義:輸出區間 [x,y][x,y] 內每個數的和對 pp 取模所得的結果

輸出格式

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

輸入輸出樣例

輸入 #1 複製

5 5 38

1 5 4 2 3

2 1 4 1

3 2 5

1 2 4 2

2 3 5 5

3 1 4

輸出 #1 複製172

#include

#include

#define maxn 1000001

#define ll long long

using

namespace std;

ll a[

500010

],tree[

500010

],tag1[

500010

],tag2[

500010];

int x,y,p;

void

build

(int start,

int end,

int now)

else

}//a是加法的引數 b是乘法的引數

void

pushlazy

(int l,

int r,

int now,ll a,ll b)

void

dowlazy

(int l,

int r,

int now)

void

fun(

int l,

int r,

int now,ll a,ll b)

}ll ask

(int l,

int r,

int now)

intmain()

build(1

,n,1);

while

(m--

)else

if(flag==2)

else

}}

線段樹 區間乘法

如題,已知乙個數列,你需要進行下面三種操作 將某區間每乙個數乘上 x 將某區間每乙個數加上 x 求出某區間每乙個數的和 第一行包含三個整數 n,m,p 分別表示該數列數字的個數 操作的總個數和模數。第二行包含 n 個用空格分隔的整數,其中第 i 個數字表示數列第 i 項的初始值。接下來 m 行每行包...

線段樹(區間樹)

目錄 為什麼要使用線段樹 什麼是線段樹 線段樹融合介面 線段樹實現 線段樹例題 融合介面 author administrator param public inte ce merger package com.suanfa.segmenttree 線段樹 區間樹 author administra...

線段樹 區間樹

每乙個節點儲存的是乙個區間中相應統計值 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treeindex,int l,int r int lefttreeindex leftchild treeindex int rig...