洛谷 P2042 NOI2005 維護數列

2022-05-06 22:12:12 字數 2281 閱讀 2937

一直在想要做這道題,但是被那個碩大的splay標籤壓垮了

好了,切入正題

這道題應該是我第二次用splay來維護區間問題 我還是太菜了qaq

其實思路也很簡單,就是以每乙個位置的下標來進行維護,然後其實就是跟權值樹是一模一樣的了

然後再具體說一下

為了保證效率,像線段樹和文藝平衡樹一樣,我們可以維護乙個\(\),然後在需要向下查詢時再向下查詢就行

然後我們考慮兩種標記各自下傳的先後順序

我們可以發現,如果乙個區間內已經被「同化」,即進行了\(make-same\)操作,這個時候,翻轉也沒有了意義。

關於求最大子段和,這個部分就跟原來用線段樹解決此類問題是一模一樣的,維護乙個gss標記,然後對其做dp就行了。

然後這一道題和其他平衡樹的題最大的一點不同是它是區間插入,區間刪除。為了提公升效率,我們可以考慮先將每一次要加入的一段區間預處理成一棵平衡樹,然後再直接插入,這樣的話效率會有很大的提公升

然後,這道題差不多就完了

具體就看**吧

#pragma g++ optimize(3)

#pragma gcc optimize(3)

#pragma g++ optimize(2)

#pragma gcc optimize(2)

#pragma g++ optimize("-ofast")

#pragma gcc optimize("-ofast")

#include#include#include#define dir(p) (son[fa[p]][1]==p)

#define inf 0x3f3f3f

using namespace std;

const int maxn=6e5+10;

char opt[30];

int n,m,ncnt,root;

queueq;

int siz[maxn],son[maxn][2],sum[maxn],val[maxn];

int gss[maxn],lx[maxn],rx[maxn],fa[maxn];

int sam[maxn],rev[maxn],a[maxn],id[maxn];

void swap(int &a,int &b)

int max(int a,int b)

inline int read()

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

return num*f;

}void upd(register int t)

void pushdown(register int t)

if(r)

}if(rev[t]) }

inline int node(register int x)

inline int kth(register int x)

else

return t; }}

void rotate(register int p)

void splay(register int p,register int g)

rotate(p);

} if(!g) root=p;

}inline void insert(register int x,register int y)

inline void recycle(register int x)

inline void remove(register int x,register int y)

inline int qsum(register int x,register int y)

int build(register int l,register int r,int *qaq)

inline void update(register int x,register int y,register int z)

inline void reverse(register int x,register int y)

}int main()

else if(opt[0]=='d')

else if(opt[0]=='m'&&opt[3]=='e')

else if(opt[0]=='r')

else if(opt[0]=='g')

else if(opt[0]=='m'&&opt[1]=='a'&&opt[2]=='x')

printf("%d\n",gss[root]);

} return 0;

}

P2042 NOI2005 維護數列

超級噁心的pushdown 昏天黑地的調 讓我想起了我那前幾個月的線段樹2 這噁心的一道題終於過了 太多錯誤,簡直說不過來 pushup pushdown 主要就是這倆不太清晰,亂pushdown 其他的寫的還沒啥毛病 能看出來 include include include include inc...

P2042 NOI2005 維護數列

這道題看到什麼維護序列的,肯定就是用資料結構的。這個東西叫你做下面的事情 首先確定用什麼資料結構。看到翻轉,二話不說就用splay。第乙個操作 在第posi位後加入tot個數字。我們就把這一段數字建出乙個子splay。用類似線段樹的建樹方式解決掉,比乙個乙個加入的建樹方式快,常數小。然後split出...

P2042 NOI2005 維護數列 平衡樹

最大序列和小白逛公園做過 區間修改的優先順序高於區間翻轉的優先順序 之前有題01串翻轉 序列維護平衡樹 平衡樹維護的是下標 因此中序遍歷就是原序列 每個結點維護的都是結點 不像線段樹可以維護區間 所以build 的操作有一些不一樣 這題還卡空間 所以要弄乙個簡單的 操作 注意up的順序 必須從下到上...