陳年老題。。。
我就$%^&。。。
碼了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的根節點連到對應的點的兒子節點即可。然...