題目在這裡
這應該是splay裸題了吧。對於每個節點儲存5個值,size,_max,flag,lazy,val 分別表示這個節點的子樹大小,子樹的最大值,子樹是否有打過翻轉標記,子樹的增加的值,(前面的所有都包括這個節點它自己),以及這個節點的當前值。對於一段區間[l,r]的詢問/修改,只需把l-1這個節點旋轉到根,再把r+1這個節點旋轉到根的右兒子。這樣r+1節點的左子樹就對應[l,r]這個區間,之後就直接在它的左兒子上打標記/詢問就行了。當然為了方便新建兩個節點乙個代表0,另乙個代表n+1。(好像學名叫殭屍節點。。。)對於add操作,直接所有值加v;而對於翻轉操作,直接交換這個節點的左右兒子就行了(大概意會一下)。注意這樣搞完之後,下標為i的節點不一定代表s[i],而是要根據二叉查詢樹的定義查詢(比如當前找第k個點,如果左子樹大小小於k-1就往左子樹里找,如果等於k-1就是它自己,如果大於k-1就k-=size[lson[x]],然後往右子樹裡找)。pushdown操作模擬一下線段樹,即只要到這個點就把它的pushdown下去,然後把這個點的標記清空。然後每次幹完之後update一下(注意最大值還要跟當前的val比較)。這樣應該就差不多了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int maxn=50005,inf=(1
<<29);
int n,m,root;
class splay_tree
void add(int x,int v)
void update(int x)
void pushdown(int x)
void rotate(int x,int d)
void splay(int x,int goal)
}update(x);
if (goal==0) root=x;
}int find(int x)
return nowx;
}public:
void build_tree(int l,int r,int f)
void modify(int ql,int qr)
void add(int ql,int qr,int v)
void query(int ql,int qr)
int select(int ql,int qr)
/*void debug(int x)
*/}t;int get()
int main()
return
0;}
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。尤其是我們這裡的某人,出模擬試題,居然還出了一道這樣的,真是沒技術含量 這樣,我也出一道題,我出這一道的目的是為了讓大家以後做這種題目有乙個 庫 可以依靠,沒有什麼其他的意思...
BZOJ 1251 序列終結者
題意 給定含有n個0的的數列。1.區間加值 2.區間翻轉 3.區間求最大值 演算法 平衡樹 fhq treap 需要特別注意的是 1.使0點對全域性無影響並全程保持 例如求max,t 0 mx inf 2.平衡樹和線段樹的上傳區別在於要考慮本身這個點。include include include ...