輸入的第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 #include5view codeusing
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 }
【fhq-treap】
1 #include2 #include3 #include4 #include5view codeusing
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 }
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 內。插入的數字總數不...