序列終結者(bzoj 1521)

2022-05-14 06:41:14 字數 1652 閱讀 7423

網上有許多題,就是給定乙個序列,要你支援幾種操作:a、b、c、d。一看另一道題,又是乙個序列 要支援幾種操作:d、c、b、a。尤其是我們這裡的某人,出模擬試題,居然還出了一道這樣的,真是沒技術含量……這樣 我也出一道題,我出這一道的目的是為了讓大家以後做這種題目有乙個「庫」可以依靠,沒有什麼其他的意思。這道題目 就叫序列終結者吧。 【問題描述】 給定乙個長度為n的序列,每個序列的元素是乙個整數(廢話)。要支援以下三種操作: 1. 將[l,r]這個區間內的所有數加上v。 2. 將[l,r]這個區間翻轉,比如1 2 3 4變成4 3 2 1。 3. 求[l,r]這個區間中的最大值。 最開始所有元素都是0。

第一行兩個整數n,m。m為操作個數。 以下m行,每行最多四個整數,依次為k,l,r,v。k表示是第幾種操作,如果不是第1種操作則k後面只有兩個數。

對於每個第3種操作,給出正確的回答。

4 41 1 3 2

1 2 4 -1

2 1 3

3 2 4

2【資料範圍】

n<=50000,m<=100000。

/*

學習了一下splay關於區間的操作

對於乙個區間操作,我們要將樹上的權值設為原序列的編號,當詢問x-y時,把x-1轉到樹根,y+1轉到x-1的右孩子,

這樣一來,x-y就是x-1的左子樹。

需要注意的是,可能會有1-n的詢問,所以需要加兩個「哨兵」。

*/#include

#include

#define n 50010

#define inf 1000000000

using

namespace

std;

int tr[n][2

],size[n],w[n],fa[n],n,m,rt;

inttag[n],rev[n],mx[n],id[n];

void up_data(int

x)void push_down(int

x)

if(rev[x])

}void rotate(int x,int &k)

fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;

tr[y][l]=tr[x][r];tr[x][r]=y;

up_data(y);up_data(x);

}void splay(int x,int &k)

rotate(x,k);

}}int find(int &k,int

rk)void build(int l,int r,int

f) build(l,mid-1,mid);build(mid+1

,r,mid);

fa[now]=last;up_data(now);

if(now0]=now;

else tr[last][1]=now;

}void add(int l,int r,int

v)void rever(int l,int

r)int solvemx(int l,int

r)int

main()

if(opt==2

) rever(x,y);

if(opt==3) printf("

%d\n

",solvemx(x,y));

}return0;

}

序列終結者

時間限制 1 sec 記憶體限制 128 mb 題目描述 給定乙個長度為n的序列,每個序列的元素是乙個整數。要支援以下三種操作 1.將 l,r 這個區間內的所有數加上v。2.將 l,r 這個區間翻轉,比如1 2 3 4變成4 3 2 1。3.求 l,r 這個區間中的最大值。最開始所有元素都是0。輸入...

序列終結者 Splay

1.注意在 split 和 merge 時要特判一下邊界,否則就會出現邊界錯誤的情況。2.隨時都要維護父指標。3.在更新 maxv 和翻轉標記時要判一下左右兒子是否都存在。include include includeusing namespace std const int maxn 100000...

序列終結者 Splay

1.注意在 split 和 merge 時要特判一下邊界,否則就會出現邊界錯誤的情況。2.隨時都要維護父指標。3.在更新 maxv 和翻轉標記時要判一下左右兒子是否都存在。include include includeusing namespace std const int maxn 100000...