輸入的第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
這題一看就是splay的水題,邊界處理的要死了,第一遍用的splay,第二遍是fhqtreap實在是比splay好打,對於邊界我是加了哨兵節點,不過在push_down和change的時候要判斷一下,防止哨兵節點被修改,就因為這個被卡了好久,然後就沒什麼了,maintain函式要寫好一點。注意下細節就好了。
code:
#include #define inf 0x3f3f3f3f#define maxn 500005
using namespace std;
int lst[maxn],n,m;
int read()
struct node
void push_down();
node(int x);
void* operator new(size_t);
void operator delete (void* p);
}*null=new node(),*c,*mempool,*root;
typedef pairpa;
vectorbin;
void change_tag(node *p,int val)
void change_filp(node *p)
node :: node(int x)
void node :: push_down()
if(tag)}
void node :: maintain()
void* node :: operator new(size_t)
else
p = c ++;
}return p;}
void node :: operator delete(void *p)
pa spilt(node *o,int k)
else}
node* merge(node *a,node *b)
else}
int rank(int x)
return ans;}
void make_same(int pos,int tot)
void make_filp(int pos,int tot)
node *build(int l,int r)
void insert(int pos,int tot)
void dfs(node *p)
void erase(int pos,int tot)
inline int max_sum()
inline void sum(int pos,int tot)
pa x = spilt(root,pos-1);
pa y = spilt(x.second,tot);
printf("%d\n",y.first->sum);
node *tmp = merge(y.first,y.second);
root = merge(x.first,tmp);}
void dfs1(node *p)
int main()
continue;
}int pos = read(),tot=read();
if(opt[0]=='i')insert(pos,tot);
if(opt[0]=='g')sum(pos,tot);
if(opt[0]=='d')erase(pos,tot);
if(opt[0]=='r')make_filp(pos,tot);}}
BZOJ 1500, 維修數列
傳送門 編寫乙個支援插入 刪除 修改 翻轉 求和以及求和最大子串行的資料結構。splay無疑。但是寫太醜也是會tle的,比方說插入的時候應該以建樹的形式插入,而不是乙個點乙個點的形式。實現起來要注意的細節很多,對練習打splay挺有好處。陸陸續續除錯了好多天,總算在崩潰之前ac了 include c...
BZOJ 1500 維修數列
time limit 10 sec memory limit 64 mb submit 14433 solved 4701 submit status discuss 輸入的第1 行包含兩個數n 和m m 20 000 n 表示初始時數列中數的個數,m表示要進行的運算元目。第2行包含n個數字,描述初...
BZOJ1500 維修數列 splay
orz hzwer.lx x 表示x的子樹的中序遍歷的最左節點開始向右的最大和,可以在任意地方結束,rx x 表示x這棵子樹的中序遍歷最右節點開始向左的最大和。mx x 是這棵子樹的最大值,這樣就很好維護了。tag x 是這棵子樹被全部賦值的標記,rev x 是這棵子樹被反轉的標記 include ...