bzoj1251 序列終結者 splay

2021-08-14 21:57:48 字數 1587 閱讀 1328

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

又sb了,裸的splay調半天。每個人的splay寫法都不太一樣,這種模板果然還是要自己熟悉

這裡用類似線段樹的寫法建樹,兩個tag注意push的順序即可。那一段膜標膜來的remove操作沒有什麼卵用,實際上tag已經在旋轉的時候傳掉了。仔細一想這應該是寫法的問題,大概我的寫法比較優秀

#include 

#include

#include

#define rep(i,st,ed) for (int i=st;i<=ed;++i)

const

int inf=0x7fffffff;

const

int n=500005;

std:: stack

stack;

int son[n][2],lazy[n][2],fa[n];

int size[n],mx[n],a[n],root;

int read()

void push_up(int now)

void push_down(int now)

if (son[now][1])

lazy[now][1]=0;

}if (lazy[now][0])

}void rotate(int x)

/*void remove(int x,int y)

stack.push(y);

while (!stack.empty())

}*/void splay(int x,int goal=0)

rotate(x);

}if (!goal) root=x;

}int buildtree(int l,int r)

if (mid1]=buildtree(mid+1,r);

fa[son[mid][1]]=mid;

}push_up(mid);

return mid;

}int find(int k) else now=son[now][0];

}}void operate(int &l,int &r)

void reverse(int l,int r)

void modify(int l,int r,int v)

int query(int l,int r)

int main(void) else

if (opt==2) else

if (opt==3)

}return

0;}

bzoj 1251 序列終結者

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

bzoj1251 序列終結者

time limit 20 sec memory limit 162 mb submit 2971 solved 1188 submit status discuss 網上有許多題,就是給定乙個序列,要你支援幾種操作 a b c d。一看另一道題,又是乙個序列 要支援幾種操作 d c b a。尤其是...

BZOJ 1251 序列終結者

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