bzoj 1251 序列終結者

2021-07-08 09:18:40 字數 1469 閱讀 1582

題目在這裡

這應該是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 ...