P2042 NOI2005 維護數列 平衡樹

2022-05-01 13:48:07 字數 1980 閱讀 9421

最大序列和小白逛公園做過 

區間修改的優先順序高於區間翻轉的優先順序(之前有題01串翻轉)

序列維護平衡樹 平衡樹維護的是下標  因此中序遍歷就是原序列

每個結點維護的都是結點  不像線段樹可以維護區間  所以build 的操作有一些不一樣 

這題還卡空間  所以要弄乙個簡單的**操作

注意up的順序  必須從下到上  因為這個wa了好久

非常好(難調)的平衡樹題

#includeusing

namespace

std;

//input by bxd

#define rep(i,a,b) for(int i=(a);i<=(b);i++)

#define repp(i,a,b) for(int i=(a);i>=(b);--i)

#define ll long long

#define see(x) (cerr<

#define inf 0x3f3f3f3f

#define clr(a,v) memset(a,v,sizeof a)typedef pair

pii;

/////////////////////////////////

/const

int n=2e6+10

;queue

q;int lmax[n],rmax[n],siz[n],son[n][2

],id[n],sum[n],maxans[n],fa[n],lson,rson,col[n],rev[n],root,v[n],ncnt,a[n],m,n;

int chk(int

x)void up(int

pos)

void down(int

pos)

else

}if(rev[pos])

}void rotate(int

x)void splay(int x,int goal=0

) rotate(x);

}if(!goal)root=x;

}int find1(int x,int

k)void recycle(int

x)int split(int k,int

tot)

int qsum(int k,int

tot)

void upsum(int k,int tot,int

val)

void rever(int k,int

tot)

}void del(int k,int

tot)

void build(int l,int r,int

f)

if(l1

,mid);

if(r>mid)build(mid+1

,r,mid);

v[now]=a[mid];fa[now]=pre;

up(now);son[pre][mid>=f]=now;

}void insert(int k,int

tot)

build(

1,tot,0

);

int z=id[(1+tot)>>1

];

int x=find1(root,k+1),y=find1(root,k+2

); splay(x);splay(y,x);

fa[z]=y;son[y][0]=z;

up(y);up(x);

}int

main()

if(ch[0]=='r'

)rever(k,tot);

if(ch[0]=='

g')printf("

%d\n

",qsum(k,tot));

}return0;

}

view code

P2042 NOI2005 維護數列

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

P2042 NOI2005 維護數列

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

洛谷 P2042 NOI2005 維護數列

一直在想要做這道題,但是被那個碩大的splay標籤壓垮了 好了,切入正題 這道題應該是我第二次用splay來維護區間問題 我還是太菜了qaq 其實思路也很簡單,就是以每乙個位置的下標來進行維護,然後其實就是跟權值樹是一模一樣的了 然後再具體說一下 為了保證效率,像線段樹和文藝平衡樹一樣,我們可以維護...