17.8.19B组总结
倒数第二天了,可没想到遇到了一道大难题(详细看T2),貌似要用什么LCT,莫队之类的,弄得我只好先写总结……
T1
可以说是一道水题了直接把合并果子之类的co一下就好了,用堆维护出最小值与次小值,组成新数,加入堆,再加上答案就好了。
具体实现:
var
n,i,tot:longint;
ans,g,c,g1,c1,m:extended;
tt:array[1..2]of extended;
d:array[0..200000,1..2]of extended;
procedure up(x:longint);
begin
while (x<>1)and(d[x,1]<d[x div 2,1]) do
begin
tt:=d[x];
d[x]:=d[x div 2];
d[x div 2]:=tt;
x:=x div 2;
end;
end;
procedure down(x:longint);
var
y:longint;
begin
while ((x*2<=tot)and(d[x*2,1]<d[x,1]))or((x*2+1<=tot)and(d[x*2+1,1]<d[x,1])) do
begin
y:=x*2;
if (y+1<=tot)and(d[y+1,1]<d[y,1]) then
inc(y);
tt:=d[y];
d[y]:=d[x];
d[x]:=tt;
end;
end;
begin
readln(n,m);
for i:=1 to n do
begin
readln(g);
inc(tot);
d[tot,1]:=g/m;
d[tot,2]:=1;
up(tot);
end;
for i:=1 to n-1 do
begin
g:=d[1,1];
c:=d[1,2];
d[1]:=d[tot];
dec(tot);
down(1);
g1:=d[1,1];
c1:=d[1,2];
d[1]:=d[tot];
dec(tot);
down(1);
inc(tot);
d[tot,1]:=g1+g;
d[tot,2]:=c1+c;
ans:=ans+d[tot,1];
up(tot);
end;
writeln(ans:0:6);
end.
T2
乍一看跟之前(没换题前)的第三题很像,但仔细一看,数据差了可不止一点半点。
考试由于我手贱,打错了两个变量,暴力分20没了。正解好像是什么LCA之类的神(sha)犇(bi)算法初一大部分神犇都弃了。。。
T3
不要觉得题目很难,这题说来说去也就是最大生成树,将总的篱笆长度减去树上的长度就好了。
var
f:array[0..20000]of longint;
a:array[0..50000,1..2]of longint;
g:array[0..50000]of extended;
b:array[0..100,0..100]of longint;
n,m,c,i,o,q,j,tot,u,v,xx,yy:longint;
x,y:array[0..20000]of extended;
ans,sum:extended;
function get(s:longint):longint;
begin
if f[s]=0 then
exit(s);
f[s]:=get(f[s]);
exit(f[s]);
end;
procedure kp(x,y:longint);
var
i,j:longint;
mid:extended;
begin
i:=x;
j:=y;
mid:=g[x];
repeat
while g[j]<mid do dec(j);
while g[i]>mid do inc(i);
if j>=i then
begin
a[0]:=a[j];
a[j]:=a[i];
a[i]:=a[0];
g[0]:=g[j];
g[j]:=g[i];
g[i]:=g[0];
inc(i);
dec(j);
end;
until i>j;
if j>x then kp(x,j);
if i<y then kp(i,y);
end;
function abs(xxx:extended):extended;
begin
if xxx<0 then
exit(-xxx);
exit(xxx);
end;
function dis(x1,y1,x2,y2:extended):extended;
begin
if x1=x2 then
exit(abs(y1-y2));
if y1=y2 then
exit(abs(x1-x2));
exit(sqrt(sqr(x1-x2)+sqr(y1-y2)));
end;
begin
readln(n,m);
for i:=1 to n do
readln(x[i],y[i]);
for i:=1 to m do
begin
readln(u,v);
a[i,1]:=u;
a[i,2]:=v;
g[i]:=dis(x[u],y[u],x[v],y[v]);
sum:=sum+g[i];
end;
kp(1,m);
tot:=0;
for i:=1 to m do
begin
xx:=get(a[i,1]);
yy:=get(a[i,2]);
if xx<>yy then
begin
f[xx]:=yy;
ans:=ans+g[i];
inc(tot);
if tot>=n-1 then
break;
end;
end;
writeln((sum-ans):0:9);
end.