转移阵地,我们继续(伤害)
---------------------------------------------(我是分割线)-------------------------------------------------
T1:city
题目:给定一棵最小生成树(保证唯一),求其完全图的最小边权和
数据规模:对于100%的数据,点数n≤20000
思路:手动模拟一次,发现对于最后完全图的边分为两种情况,一种是于最小生成树内的,另外一种是新加的。对于所有新加的边,为了保证最小生成树的唯一,设从i->j经过的边长分别为a,b,c,那么显然可得,i到j之间的最小边长min(i,j)=max{a,b,c}+1,考虑最小生成树内的每一条边都会有对答案的贡献,那么将每一条边按权值由大到小排序后,每一条边对于答案的贡献即为(w+1)*siz[fx]*siz[fy]-1,之后将这条边擦去。以上操作均可以用并查集完成。
代码:
const
maxn=40000;
type
rec=record
x,y,w:longint;
end;
var
a:array[1..maxn] of rec;
f,siz:array[1..maxn] of longint;
i,n,fx,fy:longint;
ans:int64;
procedure qsort(l,r:longint);
var
i,j:longint;
mid,tmp:rec;
begin
i:=l; j:=r; mid:=a[(l+r) div 2];
repeat
while a[i].wmid.w do dec(j);
if i<=j then
begin
tmp:=a[i];
a[i]:=a[j];
a[j]:=tmp;
inc(i);
dec(j);
end;
until i>j;
if i
T2:coin
题目:给定n种硬币,每种硬币的面值为ai,各有无限个。有T个询问,询问能否用给出的n种硬币凑出面值M,输出最小的硬币个数,否则输出-1
数据规模:对于100%的数据,n≤100,1≤ai≤10^3,1≤M≤10^16,1≤T≤10^5
思路:乍一看,怎么感觉都是背包问题,但是一看数据规模就知道没那么简单。换个角度思考,当M在没有到达一个一定的范围之前,无脑拿最大的肯定是最优的,那在进入到一定范围之后,选取最优值即可,而明显那一部分是我们可以预处理的,鉴于M的范围,选择背包预处理1~max(ai)^2,那么ans[M]=op+f[M-op*mx],op=(M-max(ai)^2-1) div mx+1
代码:
const
inf=1684300900;
var
a:array[1..2000] of longint;
f:array[1..2000000] of longint;
n,i,j,t:longint;
m,ans,mx,op,tmp:int64;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
function min(a,b:longint):longint;
begin
if a0 do
begin
readln(m);
dec(t);
if (m<=sqr(mx)) then
begin
if f[m]<>inf then writeln(f[m]) else writeln(-1);
continue;
end;
op:=(m-sqr(mx)-1) div mx+1;
if f[m-op*mx]=inf then writeln(-1) else writeln(f[m-op*mx]+op);
end;
end.
题目:SingleLyra是一名考古学家,有一天他发现了远古时期的一段文本,这段文本是一个严格上升的十进制数序列,然而现在所有数字连在了一起,因此SingleLyra只能得到一个十进制字符串。 SingleLyra想恢复出来这段文字,为了更加符合原始文本,需要将序列的最后一个数字尽可能小,在此基础上,要求这个序列的字典序尽量大。(字典序尽量大指的是,如果有相同的方案,要求第一个数最大,若第一个数相同,要求第二个数最大,以此类推)。 注意:恢复时允许前导0的出现。
数据规模:对于 30% 的数据:1<=|S|<=2000; 对于 100% 的数据:1<=|S|<=100000