給定乙個n的排列,用它建出二叉搜尋樹。輸出每次插入後所有節點兩兩之間距離和。
n≤100000
考慮離線做。
首先把這棵樹建出來。建樹可以o(n),具體點:可以發現,插入乙個值x時,它一定是之前已經插入的數中,和它相鄰的兩個數中後插入的數值兒子。
比如:4 7 3 1 8 2 6 5。1是3的左兒子,2是1的右兒子,6是8的左兒子。
建出樹之後,把排列中的數按順序放進來。假設知道了前i-1個數的答案,現在要求前i個答案,只要加上i到其它所有節點的距離和。
那麼可以用點分治做。具體就不說了。
時間複雜度o(
nlog
n)
#include
#include
#include
#include
using namespace std;
const int n=100005,log=18;
typedef long long ll;
int n,e[n][3],m,a[n],f1[n],f2[n],cnt[n],son_cnt[n][3],rmq[n*2][log],tot,la[n],dep[n],fa[n],dfn[n],size[n],ap[n];
ints[n],r,v;
ll dis[n],son_dis[n][3],ans;
bool bz[n];
char c;
intread()
int get(int
x,int
*f)void init(intx)}
void find(int
x,int
y) m=max(m,m-s[x]);
if (mx;
}}int dfs(int
x) return r;
}int getlca(int
x,int
y)int main()
memset(f1,255,sizeof(f1));
memset(f2,255,sizeof(f2));
for (int i=n;i>1;i--)
else
}init(a[1]);
for (int j=1;jfor (int i=0;i<=tot-(1
m=n; bz[0]=1;
fa[dfs(a[1])]=0;
for (int i=1;i<=n;i++)
printf("%lld\n",ans);
}return
0;}
51nod 1297 管理二叉樹
乙個初始為空的二叉搜尋樹t,以及1到n的乙個排列p 我們向這個二叉搜尋樹t新增這些數,從a1開始,接下來是 a2,以an結束。在每乙個新增操作後,輸出t上每對節點之間的距離之和。例如 4 7 3 1 8 2 6 5。最終的二叉樹為 4 3 7 1 6 8 2 5 節點兩兩之間的距離和 6 5 5 4...
51nod1297 管理二叉樹 點分治
乙個初始為空的二叉搜尋樹t,以及1到n的乙個排列p 我們向這個二叉搜尋樹t新增這些數,從a1開始,接下來是 a2,以an結束。在每乙個新增操作後,輸出t上每對節點之間的距離之和。建樹暴力會超時,觀察可知乙個點只會掛在比它小的點中最大的點的右邊或比它大的點中最小的點的左邊,並且有且只有乙個位置是空的,...
二叉樹 二叉樹
題目描述 如上所示,由正整數1,2,3 組成了一顆特殊二叉樹。我們已知這個二叉樹的最後乙個結點是n。現在的問題是,結點m所在的子樹中一共包括多少個結點。比如,n 12,m 3那麼上圖中的結點13,14,15以及後面的結點都是不存在的,結點m所在子樹中包括的結點有3,6,7,12,因此結點m的所在子樹...