線段樹常用操作

2021-08-07 16:21:33 字數 3071 閱讀 7598

系列操作i

題目描述

給出序列 a1,a2,…,an (0≤ai≤10^9) ,有關於序列的兩種操作:

1. ai (1≤i≤n)  加上x(-10^3≤x≤10^3)

2. 求 max (1≤l≤r≤n)

輸入格式

第一行包含兩個數 n(1≤n≤10^5)和 m(1≤m≤10^5),表示序列長度和操作次數。

接下來一行n個數,以空格隔開,表示 a1,a2,…,an。

接下來 m 行,每行為以下兩種格式之一。

0 i x ,表示 ai 加上 x 。

1 l r ,求 max。

輸出格式

對於每次詢問,輸出單獨的一行表示答案。

樣例資料 1

輸入5 3 

1 2 3 4 5 

1 1 5 

0 5 -5 

1 1 5

輸出5 4

#include using namespace std;

const int max=100010;

struct cz1;

cz1 tree[max*4];

int n,m;

int a[max];

int get_int()

for(;c>='0'&&c<='9';c=getchar()) x=(x<<3)+(x<<1)+c-'0';

return x*f;

}void build(int root,int l,int r)

int mid=(l+r)/2;

build(root<<1,l,mid);

build(root<<1|1,mid+1,r);

tree[root].num=max(tree[root<<1].num,tree[root<<1|1].num);

}void add(int root,int i,int num)

int mid=(tree[root].l+tree[root].r)/2;

if(i<=mid) add(root<<1,i,num);

if(i>mid) add(root<<1|1,i,num);

tree[root].num=max(tree[root<<1].num,tree[root<<1|1].num);

}long long q(int root,int l,int r) //第一種寫法

int mid=(tree[root].l+tree[root].r)/2;

long long maxx=-10000000;

if(l<=mid) maxx=max(maxx,q(root<<1,l,r));

if(r>mid) maxx=max(maxx,q(root<<1|1,l,r));

return maxx;

}/*/long long q(int root,int l,int r) //第二種寫法

int mid=(tree[root].l+tree[root].r)/2;

if(r<=mid) return q(root<<1,l,r);

else if(l>mid) return q(root<<1|1,l,r);

else return max(q(root<<1,l,r), q(root<<1|1,l,r));

}/*/

int main()

return 0;

}

系列操作ii

題目描述

給出數列 a1,a2,…,an(0≤ai≤10^9),有關序列的兩種操作。

1. al,al+1,…,ar(1≤l≤r≤n)加上 x(-10^3≤x≤10^3)

2. 求 ai(1≤i≤n)

輸入格式

第一行包含兩個數 n(1≤n≤10^5)和 m(1≤m≤10^5),表示序列的長度和操作次數。

接下來的一行有 n 個數,以空格隔開,表示 a1,a2…an;

接下來的 m 行,每行為有以下兩種格式之一:

0 1 r x ,表示al,al+1,…,ar 加上 x。

1 i     ,求 ai 。

輸出格式

對於每次詢問,輸出單獨一行表示答案。

樣例資料 1

輸入5 3 

1 2 3 4 5 

1 5 

0 1 5 -7 

1 5輸出

5 -2

#include using namespace std;

const int max=100010;

struct cz1;

cz1 tree[max*4];

int n,m;

int a[max];

int get_int()

for(;c>='0'&&c<='9';c=getchar()) x=(x<<3)+(x<<1)+c-'0';

return x*f;

}void build(int root,int l,int r)

int mid=(l+r)/2;

build(root<<1,l,mid);

build(root<<1|1,mid+1,r);

}void add(int root,int l,int r,int num)

int mid=(tree[root].l+tree[root].r)/2;

if(l<=mid) add(root<<1,l,r,num);

if(r>mid) add(root<<1|1,l,r,num);

}void pushdown(int root)

int q(int root,int pos)

pushdown(root);

int mid=(tree[root].l+tree[root].r)/2;

if(pos<=mid) return q(root<<1,pos);

else return q(root<<1|1,pos);

}int main()

else

{int pos;

pos=get_int();

cout<

常用模板 線段樹單點操作

輸入 第一行兩個整數n,m,第二行n個整數表示初始時的陣列a 接下來m行,每行3個整數a,b,c,如果a 1,那麼輸出a b a c 中最大的數 若a 2,那麼將a b 改為c 輸出 每行輸出乙個整數,對應每乙個操作a 1 超級簡單的線段樹模板題,一遍就過了,子程式太多,變數更多,容易搞混很尷尬,就...

(線段樹操作)

題意 選取a序列的一段 l,r 將選中的區間按非降排序。問能否經過若干次操作後形成b序列 分析 b序列的數的總類及各個類的數目一定要與a序列相同 對b的每個位置的值,找到與之相同的a序列中還沒有被用的位置nowpos,然後判斷1到nowpos的最小值是否等於b序列的當前值,再將該位置修改為無效值 若...

線段樹 數列操作

假設有一列數 1 i n 支援如下兩種操作 1 將 ak 的值加 d k,d 是輸入的數 2 輸出 as as 1 at s,t 都是輸入的數,s t 根據操作要求進行正確操作並輸出結果。輸入格式 輸入檔案第一行乙個整數n 0 n 100000 第二行為 n 個整數,表示 的初始值。第三行為乙個整數...