bzoj1500 NOI2005 維修數列

2021-07-09 20:14:46 字數 1414 閱讀 5709

splay鼻祖級的題目??(霧。。

insert:把第pos個數(有哨兵節點)轉到root,把第pos+1個數轉到root的右兒子,然後對c建樹然後把這棵樹插到root右兒子的左兒子處

delete:把第pos個數轉到root,把第pos+tot+1個數轉到root右兒子,刪掉root右兒子的左兒子(變成0);注意**空間,所以還要把這棵子樹遍歷一邊。

make-same:像上面那樣轉,對root右兒子的左兒子-> setv=c

reverse:轉,對root右兒子的左兒子->rz^=1;

get-sum:轉,printf("%d", tr[x].sum);

max-sum:printf("%d", tr[root].mx);

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

樣例原始的那顆splay:

藍色是點在陣列tr中的編號,紫色是子樹的大小

#include #include #include #include using namespace std;

#define maxn 500010

#define inf 2000//不可以太大,否則幾個加起來就**了

#define u tr[x]

#define lc tr[x].ch[0]

#define rc tr[x].ch[1]

#define lc tr[lc]

#define rc tr[rc]

struct node

}tr[maxn];

char s[15];

int a[maxn],id[maxn],n,m,x,t,root,tot,c;

void pd(int x)

if (u.rv)

}void updata(int x)

int build(int l,int r)

void sc(int x,int y,bool z)

inline bool d(int x)

void rot(int x)

void splay(int x,int f)

if (d(x)==d(tr[x].f)) else

}updata(x);

}int find(int x,int y)

{ pd(x);

if (lc.sz+1

BZOJ1500 NOI2005 維修數列

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

BZOJ 1500 NOI2005 維修數列

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

bzoj1500 NOI2005 維修數列

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