3244: [Noi2013]树的计数 - BZOJ
Description
我们知道一棵有根树可以进行深度优先遍历(DFS)以及广度优先遍历(BFS)来生成这棵树的DFS序以及BFS序。两棵不同的树的DFS序有可能相同,并且它们的BFS序也有可能相同,例如下面两棵树的DFS序都是1 2 4 5 3,BFS序都是1 2 3 4 5
现给定一个DFS序和BFS序,我们想要知道,符合条件的有根树中,树的高度的平均值。即,假如共有K棵不同的有根树具有这组DFS序和BFS序,且他们的高度分别是h1,h2,...,hk,那么请你输出
(h1+h2..+hk)/k
Input
有3行。
第一行包含1个正整数n,表示树的节点个数。
第二行包含n个正整数,是一个1~n的排列,表示树的DFS序。
第三行包含n个正整数,是一个1~n的排列,表示树的BFS序。
输入保证至少存在一棵树符合给定的两个序列。
Output
仅包含1个实数,四舍五入保留恰好三位小数,表示树高的平均值。
Sample Input
5
1 2 4 5 3
1 2 3 4 5
Sample Output
3.500
HINT
【评分方式】
如果输出文件的答案与标准输出的差不超过0.001,则将获得该测试点上的分数,否则不得分。
【数据规模和约定】
20%的测试数据,满足:n≤10;
40%的测试数据,满足:n≤100;
85%的测试数据,满足:n≤2000;
100%的测试数据,满足:2≤n≤200000。
【说明】
树的高度:一棵有根树如果只包含一个根节点,那么它的高度为1。否则,它的高度为根节点的所有子树的高度的最大值加1。
对于树中任意的三个节点a , b , c ,如果a, b都是c的儿子,则a, b在BFS序中和DFS序中的相对前后位置是一致的,即要么a都在b的前方,要么a都在b的后方。
Orz两位神犇的题解http://www.cnblogs.com/g-word/p/3288675.html
http://www.cnblogs.com/lazycal/p/bzoj-3244.html
我太弱了,你们还是看他们两个的吧,他们讲的还是比较清楚的
1 const 2 maxn=200200; 3 type 4 node=record 5 lc,rc,l,r,min:longint; 6 end; 7 var 8 a,b,dfs,bfs,max:array[0..maxn]of longint; 9 f:array[0..maxn*2]of node; 10 n,tot:longint; 11 ans,s:double; 12 13 function min(x,y:longint):longint; 14 begin 15 if x<y then exit(x); 16 exit(y); 17 end; 18 19 procedure build(l,r:longint); 20 var 21 now,mid:longint; 22 begin 23 inc(tot);now:=tot; 24 f[now].l:=l;f[now].r:=r; 25 if l=r then 26 begin 27 f[now].min:=a[l]; 28 exit; 29 end; 30 mid:=(l+r)>>1; 31 f[now].lc:=tot+1; 32 build(l,mid); 33 f[now].rc:=tot+1; 34 build(mid+1,r); 35 f[now].min:=min(f[f[now].lc].min,f[f[now].rc].min); 36 end; 37 38 function min(now,l,r:longint):longint; 39 var 40 mid:longint; 41 begin 42 if (f[now].l>=l) and (f[now].r<=r) then exit(f[now].min); 43 mid:=(f[now].l+f[now].r)>>1; 44 min:=n; 45 if l<=mid then min:=min(min(f[now].lc,l,r),min); 46 if r>mid then min:=min(min(f[now].rc,l,r),min); 47 end; 48 49 procedure main; 50 var 51 i:longint; 52 begin 53 read(n); 54 for i:=1 to n do read(a[i]); 55 for i:=1 to n do read(b[i]); 56 for i:=1 to n do bfs[b[i]]:=i; 57 for i:=1 to n do a[i]:=bfs[a[i]]; 58 for i:=1 to n do dfs[a[i]]:=i; 59 for i:=1 to n do 60 if a[i]>max[i-1] then max[i]:=a[i] 61 else max[i]:=max[i-1]; 62 ans:=1; 63 build(1,n); 64 for i:=1 to n-1 do 65 if (i=1) or (dfs[i+1]<dfs[i]) then ans:=ans+1+s 66 else 67 if dfs[i+1]=dfs[i]+1 then 68 begin 69 if max[dfs[i]]<=i+1 then s:=s+0.5; 70 end 71 else 72 if min(1,dfs[i],dfs[i+1])<i then s:=0; 73 ans:=ans+s; 74 writeln(ans-0.001:0:3);writeln(ans:0:3);writeln(ans+0.001:0:3); 75 end; 76 77 begin 78 main; 79 end.