【NOIP提高组五校联考】排队
2016-10-05 21:25
316 查看
Description
Solution
因为每一个房间的优先级是固定的,所以可以预处理出每个房间的优先级,以此作为凭证把它插入堆中,很显然较优先的房间若是空的就一定会选取到,那么一次插入若干个人,就进行同样次数的取顶操作。记录那些点已经被占用了,显然被占用的房间一定是连续的,只要找到开头,第二问就能轻松解决,倍增就可以快速解决了。(比赛的时候想太多了,以为可能经过操作后被占用房间会断开,所以没有打倍增……)Code
var next,data:array[0..200000] of longint; last,l1,l2,t,dfn,de,p:array[0..100000] of longint; f:array[0..100000,0..20] of longint; n,m,op,q,x,y,i,j,sum,num:longint; procedure ins(x,y:longint); begin inc(sum); data[sum]:=y; next[sum]:=last[x]; last[x]:=sum; end; procedure up(x:longint); begin if x div 2=0 then exit; if dfn[t[x]]<dfn[t[x div 2]] then begin t[0]:=t[x];t[x]:=t[x div 2];t[x div 2]:=t[0]; up(x div 2); exit; end; end; procedure down(x:longint); var s:longint; begin s:=x; if (x*2<=sum)and(dfn[t[s]]>dfn[t[x*2]]) then s:=x*2; if (x*2+1<=sum)and(dfn[t[s]]>dfn[t[x*2+1]]) then s:=x*2+1; if s=x then exit; t[0]:=t[x];t[x]:=t[s];t[s]:=t[0]; down(s); end; procedure qsort(l,r:longint); var i,j,mid:longint; begin i:=l;j:=r; mid:=t[(i+j)div 2]; repeat while t[i]>mid do inc(i); while mid>t[j] do dec(j); if i<=j then begin t[0]:=t[i];t[i]:=t[j];t[j]:=t[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j); end; procedure dfs(x,fa:longint); var i:longint; begin i:=last[x];num:=0; while i<>0 do begin if data[i]<>fa then begin inc(num); t[num]:=data[i]; end; i:=next[i]; end; qsort(1,num); for i:=1 to num do begin inc(sum); l1[sum]:=x;l2[sum]:=t[i]; end; i:=last[x]; while i<>0 do begin if data[i]<>fa then dfs(data[i],x); i:=next[i]; end; end; procedure deal(x,fa,deep:longint); var i:longint; begin de[x]:=deep; f[x,0]:=fa; i:=1; while f[f[x,i-1],i-1]<>0 do begin f[x,i]:=f[f[x,i-1],i-1]; inc(i); end; i:=last[x]; while i<>0 do begin deal(data[i],x,deep+1); i:=next[i]; end; inc(num);dfn[x]:=num; inc(sum);t[sum]:=x; up(sum); end; function jump(x:longint):longint; var i:longint; begin jump:=x; while p[f[jump,0]]=1 do begin i:=1; while p[f[jump,i]]=1 do inc(i); dec(i); jump:=f[jump,i]; end; exit(jump); end; begin readln(n,m); for i:=1 to n-1 do begin readln(x,y); ins(x,y); ins(y,x); end; sum:=0; dfs(1,0); fillchar(data,sizeof(data),0); fillchar(last,sizeof(last),0); fillchar(next,sizeof(next),0); fillchar(t,sizeof(t),0); sum:=0; for i:=1 to n-1 do ins(l1[i],l2[i]); sum:=0;num:=0; deal(1,0,1); for i:=1 to m do begin readln(op,q); case op of 1: for j:=1 to q do begin if j=q then writeln(t[1]); p[t[1]]:=1;t[1]:=0; t[0]:=t[sum];t[sum]:=t[1];t[1]:=t[0]; dec(sum); down(1); end; 2: begin x:=jump(q); writeln(de[q]-de[x]); p[x]:=0; inc(sum); t[sum]:=x; up(sum); end; end; end; end.
相关文章推荐
- 【NOIP2016提高A组五校联考1】排队
- 【JZOJ4811】【NOIP2016提高A组五校联考1】排队
- 【NOIP2016提高A组五校联考1】排队
- 【NOIP2016提高A组五校联考1】排队
- JZOJ 4811 【NOIP2016提高A组五校联考1】排队
- 【NOIP2016提高A组五校联考1】排队
- 【NOIP2016提高A组五校联考1】排队
- 【JZOJ4809】【NOIP2016提高A组五校联考1】挖金矿
- 【NOIP2016提高A组五校联考1】道路规划
- 【NOIP2016提高A组五校联考1】总结
- NOIP 2013 - 提高组 火柴排队 归并排序+逆序对 重庆一中高2018级竞赛班第六次测试 2016.7.31 Problem 4
- NOIP2013提高组 B.火柴排队 (逆序对)
- 【JZOJ4810】【NOIP2016提高A组五校联考1】道路规划
- 洛谷P1966 火柴排队[NOIP提高组2013]
- 【NOIP提高组五校联考】道路规划
- 【NOIP2013提高组day1】火柴排队
- NOIp 2013 提高组 火柴排队 题解
- 【NOIP2013提高组】火柴排队
- Noip提高2013 Day1 T2 火柴排队 归并求逆序对