bzoj 1089 SCOI2003严格n元树 递推
挺好想的,就是一直没调过,我也不知道哪儿的错,对拍也拍了,因为数据范围小,都快手动对拍了也不知道
哪儿错了。。。。
我们定义w[i]代表深度<=i的严格n元树的个数
那么最后w[d]-w[d-1]就是答案
那么对于w[i],我们由w[i-1]递推来,
我们考虑新加一个根节点,然后根节点有n个子节点,每个子节点都可以建一颗深度<=i-1的树,那么每个
子节点都有w[i-1]种选法,那么n个子节点就有w[i-1]^n选法,再加上都不选,就是深度为0的情况
那么w[i]:=(w[i-1]^n)+1;
//By BLADEVIL var w :array[-1..100] of ansistring; n, d :longint; a, b, c :array[0..100000] of int64; function mul(s1,s2:ansistring):ansistring; var i, j :longint; len1, len2 :longint; s :ansistring; begin len1:=length(s1); len2:=length(s2); fillchar(c,sizeof(c),0); fillchar(a,sizeof(a),0); fillchar(b,sizeof(b),0); for i:=1 to len1 do a[(len1-i) div 4+1]:=a[(len1-i) div 4+1]*10+ord(s1[i])-48; for i:=1 to len2 do b[(len2-i) div 4+1]:=b[(len2-i) div 4+1]*10+ord(s2[i])-48; len1:=(len1+3) div 4; len2:=(len2+3) div 4; for i:=1 to len1 do for j:=1 to len2 do begin c[i+j-1]:=c[i+j-1]+a[i]*b[j]; c[i+j]:=c[i+j]+c[i+j-1] div 10000; c[i+j-1]:=c[i+j-1] mod 10000; end; mul:=''; len1:=len1+len2+1; for i:=len1 downto 1 do begin if c[i]<1000 then mul:=mul+'0'; if c[i]<100 then mul:=mul+'0'; if c[i]<10 then mul:=mul+'0'; str(c[i],s); mul:=mul+s; end; while (mul[1]='0') and (length(mul)>1) do delete(mul,1,1); end; function mi(x:ansistring):ansistring; var p :longint; ans, sum :ansistring; begin ans:='1'; sum:=x; p:=n; while p<>0 do begin if p mod 2=1 then ans:=mul(ans,sum); p:=p div 2; sum:=mul(sum,sum); end; mi:=ans; end; function inc(x:ansistring):ansistring; var len :longint; i :longint; s :ansistring; begin len:=length(x); for i:=1 to len do c[i]:=ord(x[i])-48; c[len]:=c[len]+1; for i:=len downto 1 do begin c[i-1]:=c[i-1]+c[i] div 10; c[i]:=c[i] mod 10; end; inc:=''; len:=len; for i:=0 to len do begin str(c[i],s); inc:=inc+s; end; while (inc[1]='0') and (length(inc)>1) do delete(inc,1,1); end; function jian(s1,s2:ansistring):ansistring; var i :longint; len1, len2 :longint; s :ansistring; begin len1:=length(s1); len2:=length(s2); fillchar(c,sizeof(c),0); for i:=1 to len1 do a[len1-i+1]:=ord(s1[i])-48; for i:=1 to len2 do b[len2-i+1]:=ord(s2[i])-48; for i:=1 to len1 do c[i]:=a[i]-b[i]; for i:=1 to len1 do if c[i]<0 then begin c[i]:=c[i]+10; c[i+1]:=c[i+1]-1; end; jian:=''; for i:=len1 downto 1 do begin str(c[i],s); jian:=jian+s; end; while (jian[1]='0') and (length(jian)>1) do delete(jian,1,1); end; procedure main; var i :longint; begin readln(n,d); if d=0 then begin writeln(1); exit; end; w[0]:='1'; for i:=1 to d do w[i]:=inc(mi(w[i-1])); writeln(jian(w[d],w[d-1])); end; begin main; end.