bzoj 1500 維修數列

2022-03-27 06:22:05 字數 2231 閱讀 5012

輸入的第1 行包含兩個數n 和m(m ≤20 000),n 表示初始時數列中數的個數,m表示要進行的運算元目。

第2行包含n個數字,描述初始時的數列。

以下m行,每行一條命令,格式參見問題描述中的**。

任何時刻數列中最多含有500 000個數,數列中任何乙個數字均在[-1 000, 1 000]內。

插入的數字總數不超過4 000 000個,輸入檔案大小不超過20mbytes。

對於輸入資料中的get-sum和max-sum操作,向輸出檔案依次列印結果,每個答案(數字)佔一行。

9 82 -6 3 5 1 -5 -3 6 3

get-sum 5 4

max-sum

insert 8 3 -5 7 2

delete 12 1

make-same 3 3 2

reverse 3 6

get-sum 5 4

max-sum

-110110

這題一看就是splay的水題,邊界處理的要死了,第一遍用的splay,第二遍是fhqtreap實在是比splay好打,對於邊界我是加了哨兵節點,不過在push_down和change的時候要判斷一下,防止哨兵節點被修改,就因為這個被卡了好久,然後就沒什麼了,maintain函式要寫好一點。注意下細節就好了。

code:

#include #define inf 0x3f3f3f3f

#define maxn 500005

using namespace std;

int lst[maxn],n,m;

int read()

struct node

void push_down();

node(int x);

void* operator new(size_t);

void operator delete (void* p);

}*null=new node(),*c,*mempool,*root;

typedef pairpa;

vectorbin;

void change_tag(node *p,int val)

void change_filp(node *p)

node :: node(int x)

void node :: push_down()

if(tag)}

void node :: maintain()

void* node :: operator new(size_t)

else

p = c ++;

}return p;}

void node :: operator delete(void *p)

pa spilt(node *o,int k)

else}

node* merge(node *a,node *b)

else}

int rank(int x)

return ans;}

void make_same(int pos,int tot)

void make_filp(int pos,int tot)

node *build(int l,int r)

void insert(int pos,int tot)

void dfs(node *p)

void erase(int pos,int tot)

inline int max_sum()

inline void sum(int pos,int tot)

pa x = spilt(root,pos-1);

pa y = spilt(x.second,tot);

printf("%d\n",y.first->sum);

node *tmp = merge(y.first,y.second);

root = merge(x.first,tmp);}

void dfs1(node *p)

int main()

continue;

}int pos = read(),tot=read();

if(opt[0]=='i')insert(pos,tot);

if(opt[0]=='g')sum(pos,tot);

if(opt[0]=='d')erase(pos,tot);

if(opt[0]=='r')make_filp(pos,tot);}}

BZOJ 1500, 維修數列

傳送門 編寫乙個支援插入 刪除 修改 翻轉 求和以及求和最大子串行的資料結構。splay無疑。但是寫太醜也是會tle的,比方說插入的時候應該以建樹的形式插入,而不是乙個點乙個點的形式。實現起來要注意的細節很多,對練習打splay挺有好處。陸陸續續除錯了好多天,總算在崩潰之前ac了 include c...

BZOJ 1500 維修數列

time limit 10 sec memory limit 64 mb submit 14433 solved 4701 submit status discuss 輸入的第1 行包含兩個數n 和m m 20 000 n 表示初始時數列中數的個數,m表示要進行的運算元目。第2行包含n個數字,描述初...

BZOJ1500 維修數列 splay

orz hzwer.lx x 表示x的子樹的中序遍歷的最左節點開始向右的最大和,可以在任意地方結束,rx x 表示x這棵子樹的中序遍歷最右節點開始向左的最大和。mx x 是這棵子樹的最大值,這樣就很好維護了。tag x 是這棵子樹被全部賦值的標記,rev x 是這棵子樹被反轉的標記 include ...