CH Round #51 - Shinrein祭 #1

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.                       
View Code

 

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.    
View Code

 

posted @ 2014-08-16 12:57  ZYF-ZYF  Views(414)  Comments(0Edit  收藏  举报