pascal栈溢出如何解决?

P2146 [NOI2015] 软件包管理器

这是代码 ```cpp type edge=record d,next:longint; end; rec=record l,r,sum,flag,mid:longint; end; var w,son,top,fa,size,first:array[0..100000]of longint; a:array[0..100000]of edge; tree:array[0..500000]of rec; n,m,i,j,x,tot,sum:longint; s1,s2:char; procedure add(x,y:longint); begin inc(tot); a[tot].d:=y; a[tot].next:=first[x]; first[x]:=tot; end; procedure dfs1(x,y:longint); var i:longint; begin fa[x]:=y; //dep[x]:=deep; i:=first[x]; size[x]:=1; while i<>0 do begin dfs1(a[i].d,x); inc(size[x],size[a[i].d]); if(son[x]=0)or(size[son[x]]<size[a[i].d]) then son[x]:=a[i].d; i:=a[i].next; end; end; procedure dfs2(x,t:longint); var i:longint; begin top[x]:=t; inc(sum); w[x]:=sum; if son[x]<>0 then dfs2(son[x],t); i:=first[x]; while i<>0 do begin if a[i].d<>son[x] then dfs2(a[i].d,a[i].d); i:=a[i].next; end; end; procedure build(k,l,r:longint); begin tree[k].l:=l; tree[k].r:=r; tree[k].flag:=-1; tree[k].mid:=(l+r)>>1; if l<>r then begin build(k*2,l,(l+r)>>1); build(k*2+1,(l+r)>>1+1,r); end; end; function change(k,l,r,x:longint):Longint; begin if tree[k].flag<>-1 then begin if tree[k].flag=0 then tree[k].sum:=0 else tree[k].sum:=tree[k].r-tree[k].l+1; if tree[k].l<>tree[k].r then begin tree[k*2].flag:=tree[k].flag; tree[k*2+1].flag:=tree[k].flag; end; tree[k].flag:=-1; end; if(tree[k].l=l)and(tree[k].r=r)then begin if x=0 then change:=-tree[k].sum else change:=tree[k].r-tree[k].l+1-tree[k].sum; tree[k].flag:=x; exit; end; if tree[k].mid>=r then change:=change(k*2,l,r,x) else if tree[k].mid<l then change:=change(k*2+1,l,r,x) else begin change:=change(k*2,l,tree[k].mid,x); change:=change+change(k*2+1,tree[k].mid+1,r,x); end; tree[k].sum:=tree[k].sum+change; end; procedure solve1(x:longint); var i,j:longint; begin i:=x; j:=0; while i<>-1 do begin inc(j,change(1,w[top[i]],w[i],1)); i:=fa[top[i]]; end; writeln(j); end; procedure solve2(x:longint); begin writeln(-change(1,w[x],w[x]+size[x]-1,0)); end; begin readln(n); for i:=1 to n-1 do begin read(x); add(x,i); end; dfs1(0,-1); dfs2(0,0); build(1,1,sum); readln(m); for i:=1 to m do begin read(s1);read(s2); while s2<>' ' do read(s2); readln(x); if s1='i' then solve1(x) else solve2(x); end; end. ```
by zmh964685331 @ 2015-07-21 14:13:38


换C++啊,多大点事,真是的
by Claude @ 2015-07-21 16:03:37


同栈溢出。。话说洛谷中Pascal的栈有多大?
by abslime @ 2015-07-27 19:38:51


感觉不科学啊,为何100000层的递归都会挂
by abslime @ 2015-07-30 23:19:03


这好办,改成人工栈就行了,附上AC代码: ```cpp program zht; type marvolo=record l:longint; r:longint; la:longint; d:longint; end; var i,j,n,m,h,q,x,tot,p:longint; time:real; z,zz:char; t:array[0..110000,1..3] of longint; a,b,a2,b2,f,s,son,w,top,right:array[0..110000] of longint; z1,z2:array[0..200000] of longint; tree:array[0..500000] of marvolo; procedure gb(low,high:longint); var q,w,e,mid,k:longint; begin if low=high then exit; mid:=(low+high) div 2; gb(low,mid); gb(mid+1,high); q:=low; w:=mid+1; e:=low; while (q<=mid) and (w<=high) do if a[q]<a[w] then begin a2[e]:=a[q]; b2[e]:=b[q]; inc(e); inc(q); end else begin a2[e]:=a[w]; b2[e]:=b[w]; inc(e); inc(w); end; if q<=mid then while q<=mid do begin a2[e]:=a[q]; b2[e]:=b[q]; inc(e); inc(q); end else while w<=high do begin a2[e]:=a[w]; b2[e]:=b[w]; inc(e); inc(w); end; for k:=low to high do begin a[k]:=a2[k]; b[k]:=b2[k]; end; end; procedure bfs1; var i:longint; begin i:=0; q:=a[1]; t[a[1],1]:=1; for i:=2 to n do if a[i]<>q then begin t[q,2]:=i-1; q:=a[i]; t[q,1]:=i; end; t[q,2]:=n; for i:=1 to n do if t[a[i],1]<>0 then t[a[i],3]:=t[a[i],2]-t[a[i],1]+1; for i:=1 to n do s[i]:=1; h:=1; z1[1]:=1; z2[1]:=t[1,3]; while h<>0 do begin if z2[h]=0 then begin inc(s[z1[h-1]],s[z1[h]]); z2[h]:=0; z1[h]:=0; dec(h); continue; end; inc(h); z1[h]:=b[t[z1[h-1],1]+t[z1[h-1],3]-z2[h-1]]; z2[h]:=t[z1[h],3]; dec(z2[h-1]); end; end; procedure chuli1; var i,j,k,q,wz:longint; begin i:=0; j:=0; k:=0; q:=0; wz:=0; for i:=1 to n do begin k:=0; q:=0; wz:=0; for j:=t[i,1] to t[i,2] do if j=0 then break else if s[b[j]]>q then begin q:=s[b[j]]; k:=b[j]; wz:=j; end; son[i]:=k; if wz<>1 then begin b[wz]:=b[t[i,1]]; b[t[i,1]]:=k; end; end; end; procedure bfs2; begin h:=1; tot:=0; fillchar(z1,sizeof(z1),0); fillchar(z2,sizeof(z2),0); z1[1]:=1; z2[1]:=t[1,3]; top[1]:=1; while h<>0 do begin if z2[h]=0 then begin right[z1[h]]:=tot+1; z1[h]:=0; z2[h]:=0; dec(h); continue; end; if son[z1[h]]<>0 then begin top[son[z1[h]]]:=top[z1[h]]; for j:=t[z1[h],1]+1 to t[z1[h],2] do top[b[j]]:=b[j]; end; inc(h); z1[h]:=b[t[z1[h-1],1]+t[z1[h-1],3]-z2[h-1]]; z2[h]:=t[z1[h],3]; w[z1[h]]:=tot+1; inc(tot); dec(z2[h-1]); end; end; procedure maketree(x,low,high:longint); var mid:longint; begin mid:=0; tree[x].l:=low; tree[x].r:=high; tree[x].la:=-1; if low=high then exit; mid:=(low+high) div 2; maketree(x*2,low,mid); maketree(x*2+1,mid+1,high) end; procedure sum(bh,yc:longint); begin tree[bh].d:=(tree[bh].r-tree[bh].l+1)*yc; tree[bh].la:=-1; if tree[bh].l=tree[bh].r then exit; tree[bh*2].la:=yc; tree[bh*2+1].la:=yc; end; procedure add(x,low,high,bj:longint); var mid:longint; begin mid:=0; mid:=(tree[x].l+tree[x].r) div 2; if tree[x].la<>-1 then sum(x,tree[x].la); if tree[x].l=tree[x].r then begin tree[x].d:=bj; exit; end; if (tree[x].l=low) and (tree[x].r=high) then begin tree[x].d:=(tree[x].r-tree[x].l+1)*bj; tree[x*2].la:=bj; tree[x*2+1].la:=bj; exit; end; if low>mid then add(x*2+1,low,high,bj) else if high<=mid then add(x*2,low,high,bj) else begin add(x*2,low,mid,bj); add(x*2+1,mid+1,high,bj); end; if tree[x*2].la<>-1 then sum(x*2,tree[x*2].la); if tree[x*2+1].la<>-1 then sum(x*2+1,tree[x*2+1].la); tree[x].d:=tree[x*2].d+tree[x*2+1].d; end; procedure install(x:longint); var zc:longint; begin zc:=0; zc:=tree[1].d; while top[x]<>1 do begin add(1,w[top[x]]+1,w[x]+1,1); x:=f[top[x]]; end; add(1,w[top[x]]+1,w[x]+1,1); writeln(tree[1].d-zc); end; procedure uninstall(bh:longint); var zc:longint; begin zc:=0; zc:=tree[1].d; add(1,w[bh]+1,right[bh],0); writeln(zc-tree[1].d); end; begin readln(n); for i:=1 to n-1 do begin read(x); inc(a[0]); a[a[0]]:=x+1; b[a[0]]:=i+1; f[i+1]:=x+1; end; f[1]:=1; gb(1,n-1); bfs1; chuli1; bfs2; maketree(1,1,n); q:=0; readln(q); for i:=1 to q do begin read(z); zz:=z; while zz<>' ' do read(zz); readln(p); if z='i' then install(p+1) else uninstall(p+1); end; end. ```
by zhtjtcz @ 2016-03-03 14:06:49


感觉手工栈写起来不太方便啊
by McGrady @ 2016-12-16 23:17:00


这个数字竟然没人考古 ~~我来做考古第一人——~~
by 飞啾6373 @ 2021-10-04 15:54:18


@[飞啾6373](/user/378928) 考古
by _Komorebi_ @ 2023-06-08 19:14:52


|