A.Phorni
题目:http://www.contesthunter.org/contest/CH%20Round%20%2351%20-%20Shinrein祭%20%231/Phorni
没做。。。
B.Arietta
题目:http://www.contesthunter.org/contest/CH%20Round%20%2351%20-%20Shinrein祭%20%231/Arietta
想到了网络流,所以每次暴力算出哪些点能被弹奏,就从这次弹奏向哪些点连容量为1的边
最后由s向所有力度连容量为该力度最多能被弹多少次的边,由每个节点连t容量为1的边
求最大流,得到了暴力分30分。正解还不会
代码:
1 const inf=maxlongint;maxn=10000+100;maxm=1000000; 2 type node=record 3 go,next,v:longint; 4 end; 5 var tot,i,n,m,maxflow,l,r,s,t,x,y,tot2:longint; 6 h,head,head2,q,cur,v:array[0..maxn] of longint; 7 e:array[0..maxm] of node; 8 e2:array[0..maxn] of node; 9 function min(x,y:longint):longint; 10 begin 11 if x<y then exit(x) else exit(y); 12 end; 13 procedure ins(x,y,z:longint); 14 begin 15 inc(tot); 16 e[tot].go:=y;e[tot].v:=z;e[tot].next:=head[x];head[x]:=tot; 17 end; 18 procedure insert(x,y,z:longint); 19 begin 20 ins(x,y,z);ins(y,x,0); 21 end; 22 function bfs:boolean; 23 var i,x,y:longint; 24 begin 25 fillchar(h,sizeof(h),0); 26 l:=0;r:=1;q[1]:=s;h[s]:=1; 27 while l<r do 28 begin 29 inc(l); 30 x:=q[l]; 31 i:=head[x]; 32 while i<>0 do 33 begin 34 y:=e[i].go; 35 if (e[i].v<>0) and (h[y]=0) then 36 begin 37 h[y]:=h[x]+1; 38 inc(r);q[r]:=y; 39 end; 40 i:=e[i].next; 41 end; 42 end; 43 exit (h[t]<>0); 44 end; 45 function dfs(x,f:longint):longint; 46 var i,y,used,tmp:longint; 47 begin 48 if x=t then exit(f); 49 used:=0; 50 i:=cur[x]; 51 while i<>0 do 52 begin 53 y:=e[i].go; 54 if (h[y]=h[x]+1) and (e[i].v<>0) then 55 begin 56 tmp:=dfs(y,min(e[i].v,f-used)); 57 dec(e[i].v,tmp);if e[i].v<>0 then cur[x]:=i; 58 inc(e[i xor 1].v,tmp); 59 inc(used,tmp); 60 if used=f then exit(f); 61 end; 62 i:=e[i].next; 63 end; 64 if used=0 then h[x]:=-1; 65 exit(used); 66 end; 67 procedure dinic; 68 var i:longint; 69 begin 70 while bfs do 71 begin 72 for i:=s to t do cur[i]:=head[i]; 73 inc(maxflow,dfs(s,inf)); 74 end; 75 end; 76 procedure insert2(x,y:longint); 77 begin 78 inc(tot2); 79 e2[tot2].go:=y;e2[tot2].next:=head2[x];head2[x]:=tot2; 80 end; 81 procedure init; 82 begin 83 tot:=1; 84 readln(n,m); 85 for i:=2 to n do begin read(x);insert2(x,i);end;readln; 86 for i:=1 to n do read(v[i]);readln; 87 end; 88 procedure dfss(x:longint); 89 var j,y:longint; 90 begin 91 if (v[x]>=l) and (v[x]<=r) then insert(i,x,1); 92 j:=head2[x]; 93 while j<>0 do 94 begin 95 y:=e2[j].go; 96 dfss(y); 97 j:=e2[j].next; 98 end; 99 end; 100 101 procedure main; 102 begin 103 s:=0;t:=n+m+1; 104 for i:=1 to n do insert(i,t,1); 105 for i:=n+1 to n+m do 106 begin 107 readln(l,r,x,y); 108 insert(s,i,y); 109 dfss(x); 110 end; 111 maxflow:=0; 112 dinic; 113 writeln(maxflow); 114 end; 115 116 begin 117 init; 118 main; 119 end.
C。Falsita
题目:http://www.contesthunter.org/contest/CH%20Round%20%2351%20-%20Shinrein祭%20%231/Falsita
我下午刚做了POI的大都市,然后看到这题的对子树的修改就想到了用dfs序+线段树懒惰标记的做法,
最后回答的时候我是O(该点分叉数)求出总数,再用同样时间复杂度的时间求出总代价,使用子树和算的
我想出题人的要求回答询问的该点的分叉树一定很多,就会卡我到超时,结果真是的。。。
于是我又很愉快的拿到了30分。。。正解还不会
代码:
1 const maxn=300000+100; 2 type node=record 3 go,next:longint; 4 end; 5 node2=record 6 l,r,lch,rch,mid,tag,sum:int64; 7 end; 8 var e:array[0..2*maxn] of node; 9 t:array[0..8*maxn] of node2; 10 head,l,r,s,a,b:array[0..2*maxn] of longint; 11 i,n,m,x,y,tot,clock:longint; 12 ch:char; 13 procedure insert(x,y:longint); 14 begin 15 inc(tot); 16 e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot; 17 end; 18 procedure dfs(x:longint); 19 var i,y:longint; 20 begin 21 inc(clock);l[x]:=clock;a[clock]:=x; 22 i:=head[x]; 23 while i<>0 do 24 begin 25 y:=e[i].go; 26 dfs(y); 27 i:=e[i].next; 28 end; 29 inc(clock);r[x]:=clock;a[clock]:=x; 30 end; 31 procedure pushup(k:longint); 32 begin 33 with t[k] do 34 begin 35 sum:=t[lch].sum+t[rch].sum; 36 end; 37 end; 38 procedure build(k,x,y:longint); 39 begin 40 with t[k] do 41 begin 42 l:=x;r:=y;mid:=(l+r)>>1;lch:=k<<1;rch:=k<<1+1;tag:=0; 43 if l=r then begin sum:=b[a[l]];exit;end; 44 build(lch,l,mid);build(rch,mid+1,r); 45 pushup(k); 46 end; 47 end; 48 procedure update(k:longint;val:int64); 49 begin 50 with t[k] do 51 begin 52 inc(tag,val); 53 inc(sum,(r-l+1)*val); 54 end; 55 end; 56 procedure pushdown(k:longint); 57 begin 58 with t[k] do 59 begin 60 if tag=0 then exit; 61 update(lch,tag);update(rch,tag); 62 tag:=0; 63 end; 64 end; 65 procedure change(k,x,y:longint); 66 begin 67 with t[k] do 68 begin 69 if l=r then begin inc(sum,y);exit;end; 70 pushdown(k); 71 if x<=mid then change(lch,x,y) else change(rch,x,y); 72 pushup(k); 73 end; 74 end; 75 procedure change2(k,x,y:longint;z:int64); 76 begin 77 with t[k] do 78 begin 79 if (l=x) and (r=y) then 80 begin 81 update(k,z);exit; 82 end; 83 pushdown(k); 84 if y<=mid then change2(lch,x,y,z) 85 else if x>mid then change2(rch,x,y,z) 86 else 87 begin 88 change2(lch,x,mid,z); 89 change2(rch,mid+1,y,z); 90 end; 91 pushup(k); 92 end; 93 end; 94 function query(k,x,y:longint):int64; 95 begin 96 with t[k] do 97 begin 98 if (l=x) and (r=y) then exit(sum); 99 pushdown(k); 100 if y<=mid then exit(query(lch,x,y)) 101 else if x>mid then exit(query(rch,x,y)) 102 else exit(query(lch,x,mid)+query(rch,mid+1,y)); 103 end; 104 end; 105 procedure init; 106 begin 107 readln(n,m); 108 for i:=2 to n do begin read(x);insert(x,i);end;readln; 109 for i:=1 to n do read(b[i]);readln; 110 dfs(1); 111 build(1,1,2*n); 112 for i:=1 to n do s[i]:=(r[i]-l[i]+1)>>1; 113 end; 114 procedure getans; 115 var ans:double; 116 a,b,c:array[0..maxn] of int64; 117 i,x,y,cnt:longint; 118 tot:int64; 119 begin 120 readln(x);a[0]:=x;b[0]:=s[x];c[0]:=trunc(query(1,l[x],r[x])/2); 121 cnt:=0; 122 i:=head[x]; 123 while i<>0 do 124 begin 125 y:=e[i].go; 126 inc(cnt); 127 a[cnt]:=y;b[cnt]:=s[y];c[cnt]:=trunc(query(1,l[y],r[y])/2); 128 dec(c[0],c[cnt]); 129 i:=e[i].next; 130 end; 131 tot:=b[0]-1; 132 for i:=1 to cnt do inc(tot,b[i]*(b[0]-b[i])); 133 tot:=tot>>1; 134 ans:=c[0]*(b[0]-1)/tot; 135 for i:=1 to cnt do ans:=ans+c[i]*(b[0]-b[i])/tot; 136 writeln(ans:0:6); 137 end; 138 procedure main; 139 begin 140 for i:=1 to m do 141 begin 142 read(ch); 143 case ch of 144 'S':begin 145 readln(x,y); 146 change(1,l[x],y);change(1,r[x],y); 147 end; 148 'M':begin 149 readln(x,y); 150 change2(1,l[x],r[x],y); 151 end; 152 'Q':getans; 153 end; 154 end; 155 end; 156 begin 157 init; 158 main; 159 end.