bzoj1251 序列終結者

2021-07-08 10:16:52 字數 2236 閱讀 9924

time limit: 20 sec  

memory limit: 162 mb

submit: 2971  

solved: 1188 [

submit][

status][

discuss]

網上有許多題,就是給定乙個序列,要你支援幾種操作: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

每次進行序列操作時,把l-1旋轉到根,把r+1旋轉到根的右兒子,r+1的左子樹就是整個區間[l,r]。

我們可以用splay的每個節點記錄該節點對應子樹的資訊,那麼每次詢問只要輸出r+1的左子樹中的最大值,即**中的mx[t[y][0]]。

為了避免splay中有節點0,我們將所有節點的編號加1。又因為要旋轉l-1和r+1,所以在splay插入節點為1到n+2。(原因顯然…大家自己腦補)

這道題用splay的提根操作達到了區間操作的目的,方法很巧妙。

另外我覺得這道題有幾點需要注意:

①要理解splay中節點的含義以及節點所記錄的資訊。

②區間的翻轉操作很巧妙,只需要將標記下傳並且交換左右子樹,並不需要修改節點的max和size。

③每次find操作都要pushdown,這樣就可以保證節點x到根的路徑上所有點都被更新,便於之後的旋轉操作。

#include#include#include#include#include#include#define f(i,j,n) for(int i=j;i<=n;i++)

#define d(i,j,n) for(int i=j;i>=n;i--)

#define ll long long

#define pa pair#define maxn 50005

#define inf 1000000000

using namespace std;

int n,m,rt=0,tot=0;

int a[maxn],fa[maxn],t[maxn][2],mx[maxn],tag[maxn],size[maxn];

bool rev[maxn];

inline int read()

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

return ret*flag;

}inline void pushup(int k)

inline void pushdown(int k)

if (r)

} if (rev[k]) }

inline void rotate(int &k,int x)

fa[x]=z;

fa[y]=x;

fa[t[x][r]]=y;

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

t[x][r]=y;

pushup(y);pushup(x);

}inline void splay(int &k,int x)

rotate(k,x); }}

inline int find(int k,int rank)

inline void add(int l,int r,int val)

inline void reverse(int l,int r)

inline void query(int l,int r)

inline void build(int l,int r,int last)

else if (flag==2) reverse(l,r);

else query(l,r);

} return 0;

}

bzoj 1251 序列終結者

題目在這裡 這應該是splay裸題了吧。對於每個節點儲存5個值,size,max,flag,lazy,val 分別表示這個節點的子樹大小,子樹的最大值,子樹是否有打過翻轉標記,子樹的增加的值,前面的所有都包括這個節點它自己 以及這個節點的當前值。對於一段區間 l,r 的詢問 修改,只需把l 1這個節...

BZOJ 1251 序列終結者

網上有許多題,就是給定乙個序列,要你支援幾種操作 a b c d。一看另一道題,又是乙個序列,要支援幾種操作 d c b a。尤其是我們這裡的某人,出模擬試題,居然還出了一道這樣的,真是沒技術含量 這樣,我也出一道題,我出這一道的目的是為了讓大家以後做這種題目有乙個 庫 可以依靠,沒有什麼其他的意思...

BZOJ 1251 序列終結者

題意 給定含有n個0的的數列。1.區間加值 2.區間翻轉 3.區間求最大值 演算法 平衡樹 fhq treap 需要特別注意的是 1.使0點對全域性無影響並全程保持 例如求max,t 0 mx inf 2.平衡樹和線段樹的上傳區別在於要考慮本身這個點。include include include ...