NOI2005 維護數列

2022-04-09 08:58:24 字數 1690 閱讀 4838

陳年老題。。。

我就$%^&。。。

碼了4k多。。。

主要就是用splay,然後處理區間上的東西

區間反轉就和模板一樣,但是要記得反轉leftmax和rightmax

區間賦值就把那個區間提取出來,然後給子樹根打個same標記,表示下面的全一樣。

區間求最大子段和就和線段樹的套路一樣。

區間插入就先弄好一顆平衡樹,然後把原平衡樹的根右兒子的的左兒子空出來插這個。

求sum就多加乙個sum就行了。刪除就把它弄成乙個單獨的子樹。

具體看**吧。。。

#include #include 

#include

#include

using

namespace

std;

queue

q;const

int n=1000005

;int val[n],fa[n],ch[n][2

],siz[n],sum[n],lmx[n],rmx[n],mx[n],a[n],n,m,rt,id[n],tot;

bool

rev[n],sam[n];

char opt[20

];void pushup(int

x) void pushdown(int

x)

else

}if(rev[x])

}void rotate(int

x) void splay(int x,int

tar)

int getpos(int

x) }

}void rec(int

x) void del(int sta,int

len)

void modify(int sta,int len,int

v) void reve(int sta,int

len)

}void build(int f,int l,int

r)

if(l1

);

if(mid1

,r);

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

pushup(now);ch[pre][mid>=f]=now;

}void insert(int sta,int

len)

build(

0,1,len);

int mid=id[(1+len)>>1],x=getpos(sta+1),y=getpos(sta+2

); splay(x,

0),splay(y,x);

fa[mid]=y;ch[y][0]=mid;

pushup(y),pushup(x);

}void getsum(int sta,int

len)

intmain()

if(opt[0]=='d'

)

if(opt[0]=='m'

)

else

}if(opt[0]=='r'

)

if(opt[0]=='

g') scanf("

%d%d

",&sta,&len),getsum(sta,len);}}

維護數列

noi2005維護數列

請寫乙個程式,要求維護乙個數列,支援以下 6 種操作 請注意,格式欄 中的下劃線 表示實際輸入檔案中的空格 操作編號 輸入檔案中的格式 說明1.插入 insert posi tot c1 c2 c tot 在當前數列的第 posi 個數字後插入 tot 個數字 c1,c2,c tot 若在數列首插 ...

NOI2005 維護數列

傳送門 我還是沒有逃過在這道題上debug好久的命運 我是使用 fhq treap 來做的這道題。寫的時候寫的挺爽的 調的時候真難受。首先我們先來說說咋做吧。前5個操作對於 fhq treap 來說不在話下,只要多打兩個標記就可以了。但是如何求最大子段和?於是乎我們再打三個標記來維護它 霧 然後我們...

NOI2005 維護數列

嘟嘟嘟 這題我寫的時候還是挺順的,邊寫邊想為啥學姐說我是 勇士 然後我用了大半天的debug時間理解了這句話 先不說那幾個把人坑到退役的點,光說這幾個操作,其實都聽基礎的。我感覺唯一要說一下的就是插入一串數 我們先把這些數建成乙個splay,然後把這個splay的根節點連到對應的點的兒子節點即可。然...