bzoj1500 NOI2005 維修數列

2022-04-30 13:00:10 字數 3983 閱讀 7969

輸入的第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

對於max-sum操作,維護:lsum:從當前區間左端點開始連續一段最大和,rsum:以當前區間右端點結尾連續一段最大和,初始化為0。然後就可以開始瞎搞了√

注意一些小細節,比如說update的時候記得判左右孩子存不存在什麼的(或初始化0這個點的mx為-inf。

【splay】

1 #include2 #include3 #include4 #include5

using

namespace

std;

6const

int inf=0x3f3f3f3f;7

const

int n=1000005

;8 queueq;

9int

n,m,root,cnt;

10int tr[n][2

],id[n],a[n],size[n],sum[n],v[n],mx[n],lx[n],rx[n],fa[n];

11bool

tag[n],rev[n];

12int

read()

1316

while(c>='

0'&&c<='9')

17return x*f;18}

19void update(int

x)20

29void pushdown(int

x)30

42else

4347}48

if(rev[x])

4954}55

void rotate(int x,int&k)

5665

void splay(int x,int&k)

6675

rotate(x,k);76}

77}78int find(int x,int

rnk)

7986

int turn(int k,int

tot)

8792

void build(int l,int r,int

f)93

102else build(l,mid-1,mid),build(mid+1

,r,mid);

103 v[now]=a[mid];fa[now]=last;update(now);

104 tr[last][mid>=f]=now;

105}

106void insert(int k,int

tot)

107118

void rec(int

x)119

126void erase(int k,int

tot)

127132

void makesame(int k,int tot,int

val)

133140

void rever(int k,int

tot)

141150

}151

void query(int k,int

tot)

152156

intmain()

157177

else

if(s[0]=='r'

)rever(k,tot);

178else

query(k,tot);

179}

180return0;

181 }

view code

【fhq-treap】

1 #include2 #include3 #include4 #include5

using

namespace

std;

6const

int n=5e5+5;7

const

int inf=0x3f3f3f3f;8

intn,m,tot,pos,val,cnt,root,rt1,rt2,rt3;

9int st[n],id[n],a[n],ch[n][11

];10

char op[15

];11

#define lc ch][0

12#define rc ch][1

13#define rnd ch][2

14#define sz ch][3

15#define v ch][4

16#define tag ch][5

17#define rev ch][6

18#define sum ch][7

19#define mx ch][8

20#define lsum ch][9

21#define rsum ch][10

22int

read()

2326

while(c>='

0'&&c<='9')

27return x*f;28}

29int max(int a,int b)

30void up(int

w)31

41void dn(int

w)42

54else

5559}60

if(w[rev])

6166}67

void dfs(int w)

68int build(int

n)69

80 st[top][rc]=w;

81 st[++top]=w;82}

83 ch[0][1]=0;dfs(st[1

]);84

return st[1

];85}86

void split(int w,int& l,int& r,int

k)87

89 dn(w);int lson=w[lc][sz];

90if(k<=lson)

91else

92up(w);93}

94int merge(int a,int

b)95

98else 99}

100void insert(int pos,int

tot)

101107

void rec(int

w)108

114void erase(int pos,int

tot)

115120

void makesame(int pos,int tot,int

val)

121129

void rever(int pos,int

tot)

130136

void query(int pos,int

tot)

137142

intmain()

143159

else

if(op[0]=='r'

)rever(pos,tot);

160else

query(pos,tot);

161}

162return0;

163 }

view code

BZOJ1500 NOI2005 維修數列

description input 輸入檔案的第1行包含兩個數n和m,n表示初始時數列中數的個數,m表示要進行的運算元目。第2行包含n個數字,描述初始時的數列。以下m行,每行一條命令,格式參見問題描述中的 output 對於輸入資料中的get sum和max sum操作,向輸出檔案依次列印結果,每個...

bzoj1500 NOI2005 維修數列

splay鼻祖級的題目?霧。insert 把第pos個數 有哨兵節點 轉到root,把第pos 1個數轉到root的右兒子,然後對c建樹然後把這棵樹插到root右兒子的左兒子處 delete 把第pos個數轉到root,把第pos tot 1個數轉到root右兒子,刪掉root右兒子的左兒子 變成0...

BZOJ 1500 NOI2005 維修數列

輸入的第1 行包含兩個數n 和m m 20 000 n 表示初始時數列中數的個數,m表示要進行的運算元目。第2行包含n個數字,描述初始時的數列。以下m行,每行一條命令,格式參見問題描述中的 任何時刻數列中最多含有500 000個數,數列中任何乙個數字均在 1 000,1 000 內。插入的數字總數不...