APIO2015题解
分组赛讲课讲了APIO2015的题,于是回去就做完了
稍微写一点题解吧
bzoj4069 逐位处理的简单题,然后就是bool型dp
然后a=1 的时候可以把一位状态干掉
当一维状态单调且是bool型dp时,我们可以用dp表示这一维状态;类似的思想也在bzoj1937出现过
var s:array[..] of int64;
n,a,b,i,j,k,p:longint;
g,c:array[..] of longint;
f:array[..,..] of boolean;
now:int64;
can:boolean; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; begin
readln(n,a,b);
for i:= to n do
begin
read(c[i]);
s[i]:=s[i-]+c[i];
end;
if a= then
begin
for p:= downto do
begin
now:=now or int64() shl int64(p);
g[]:=;
for i:= to n do
g[i]:=n+;
for i:= to n do
for j:= to i do
begin
if (s[i]-s[j-]) and now> then continue; //当前模板是0就不能为1,是1就随意,这里转化一下方便快速匹配
g[i]:=min(g[i],g[j-]+);
end;
if g[n]>b then
now:=now xor int64() shl int64(p);
end;
end
else begin
for p:= downto do
begin
now:=now or int64() shl int64(p);
fillchar(f,sizeof(f),false);
f[,]:=true;
for i:= to n do
for j:= to n do
for k:= to i do
if f[k-,j-] then
begin
f[i,j]:=((s[i]-s[k-]) and now=);
if f[i,j] then break;
end; can:=false;
for i:=a to b do
if f[n,i] then
begin
can:=true;
break;
end;
if not can then now:=now xor int64() shl int64(p);
end;
end;
for p:= downto do
now:=now xor int64() shl int64(p);
writeln(now);
end.
4069
bzoj4070 听说现场直接爆搜就过了,这……
首先每只狗只会往一个方向跳
当pi大的时候,每只狗跳的次数少,直接建图即可
当pi小的时候,每个点向外走的种类很少,建立辅助点即可
经典的分类思想,设定一个K
当pi>k,直接建图,设n个点为(i,0)
然后每个点i再建立k个辅助点(i,1)~(i,k) 代表对应跳跃能力
然后看每条狗,如果pi<=k则连向对应的辅助点
然后每个辅助点连向(i,0),表示通过(i,0)可以停下来换狗
然后跑dijkstra即可
注意k不能太大,因为内存卡得比较紧
然后我又tle了,把pi离散化后就过了……
const inf=;
type node=record
po,next,num:longint;
end;
point=record
loc,num:longint;
end; var h:array[..] of point;
e:array[..] of node;
p,d,wh:array[..] of longint;
v,c,b,f:array[..] of longint;
w:array[..,..] of longint;
r,st,en,size,i,j,tot,t,x,y,n,m,len:longint; procedure add(x,y,z:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
e[len].num:=z;
p[x]:=len;
end; procedure swap(var a,b:point);
var c:point;
begin
c:=a;
a:=b;
b:=c;
end; procedure sift(i:longint);
var j,x,y:longint;
begin
j:=i shl ;
while j<=tot do
begin
if (j<tot) and (h[j].num>h[j+].num) then inc(j);
if h[i].num>h[j].num then
begin
x:=h[i].loc;
y:=h[j].loc;
wh[x]:=j;
wh[y]:=i;
swap(h[i],h[j]);
i:=j;
j:=i shl ;
end
else break;
end;
end; procedure up(i:longint);
var j,x,y:longint;
begin
j:=i shr ;
while j> do
begin
if h[i].num<h[j].num then
begin
x:=h[i].loc;
y:=h[j].loc;
wh[x]:=j;
wh[y]:=i;
swap(h[i],h[j]);
i:=j;
j:=i shr ;
end
else break;
end;
end; begin
readln(n,m);
for i:= to m do
begin
readln(b[i],f[i]);
inc(b[i]);
if i= then st:=b[i];
if i= then en:=b[i];
v[f[i]]:=;
end;
for i:= to n do
if v[i]= then
begin
inc(r);
c[r]:=i;
v[i]:=r;
end; size:=trunc(sqrt(r));
if size> then size:=;
t:=n;
for i:= to size do
begin
for j:= to n do
begin
inc(t);
w[j,i]:=t;
add(t,j,);
end;
for j:= to n-c[i] do
begin
add(w[j,i],w[j+c[i],i],);
add(w[j+c[i],i],w[j,i],);
end;
end; for i:= to m do
if f[i]<=c[size] then
add(b[i],w[b[i],v[f[i]]],)
else begin
j:=;
while true do
begin
if b[i]+f[i]*j>n then break;
add(b[i],b[i]+f[i]*j,j);
inc(j);
end;
j:=;
while true do
begin
if b[i]-f[i]*j<= then break;
add(b[i],b[i]-f[i]*j,j);
inc(j);
end;
end; tot:=;
h[].loc:=st;
h[].num:=;
for i:= to t do
if i<>st then
begin
inc(tot);
h[tot].loc:=i;
h[tot].num:=inf;
d[i]:=inf;
wh[i]:=tot;
end; while tot> do
begin
x:=h[].loc;
if x=en then break;
if h[].num=inf then break;
wh[h[tot].loc]:=;
swap(h[],h[tot]);
dec(tot);
sift();
i:=p[x];
while i<> do
begin
y:=e[i].po;
if d[y]>d[x]+e[i].num then
begin
d[y]:=d[x]+e[i].num;
h[wh[y]].num:=d[y];
up(wh[y]);
end;
i:=e[i].next;
end;
end;
if d[en]=inf then writeln(-)
else writeln(d[en]);
end.
4070
bzoj4071 一开始看题的时候想到的是三分套三分……好像听说也能过……
我们只需要考虑起点终点在两侧的
当k=1 大家都会是中位数贪心
当k=2 分类讨论,设第一座桥在S1,第二座桥在S2
不难得到,xi+yi<S1+S2时走S1,否则走S2
这样只要对x+y排序,枚举分割点,分别对两部分求中位数即可然后在求和即可
这我们可以用权值线段树维护
顺便在UOJ上交被叉掉了,没事卡什么快排真是了……
type node=record
x,y,s:longint;
end;
point=record
s:longint;
sum:int64;
end; var c,a:array[..] of longint;
b:array[..] of node;
tree:array[..*,..] of point;
x,y,n,t,mid,m,i,k:longint;
ans,s:int64;
ch1,ch2:char; procedure min(var a:int64; b:int64);
begin
if a>b then a:=b;
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) shr ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure qsort(l,r:longint);
var i,j,x:longint;
y:node;
begin
i:=l;
j:=r;
x:=b[(l+r) shr ].s;
repeat
while b[i].s<x do inc(i);
while x<b[j].s do dec(j);
if not(i>j) then
begin
y:=b[i]; b[i]:=b[j]; b[j]:=y;
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function find(l,r,x:longint):longint;
var m:longint;
begin
while l<=r do
begin
m:=(l+r) shr ;
if c[m]=x then exit(m);
if c[m]>x then r:=m- else l:=m+;
end;
end; procedure add(i,l,r,w,x,y:longint);
var m:longint;
begin
inc(tree[i,w].s,y);
inc(tree[i,w].sum,y*c[x]);
if l<>r then
begin
m:=(l+r) shr ;
if x<=m then add(i*,l,m,w,x,y)
else add(i*+,m+,r,w,x,y);
end;
end; function get(i,l,r,w,k:longint):int64;
var m:longint;
begin
if l=r then exit(int64(k)*int64(c[l]))
else begin
m:=(l+r) shr ;
if tree[i*,w].s>=k then exit(get(i*,l,m,w,k))
else exit(tree[i*,w].sum+get(i*+,m+,r,w,k-tree[i*,w].s));
end;
end; function sum(w,n:longint):int64;
begin
exit(tree[,w].sum-*get(,,m,w,n shr ));
end; begin
readln(k,n);
for i:= to n do
begin
read(ch1);
read(x);
read(ch2); read(ch2);
readln(y);
if ch1=ch2 then s:=s+abs(x-y)
else begin
inc(t);
b[t].x:=x;
b[t].y:=y;
b[t].s:=x+y;
end;
end;
n:=t;
t:=;
for i:= to n do
begin
inc(t);
a[t]:=b[i].x;
inc(t);
a[t]:=b[i].y;
end;
sort(,t);
if k= then
begin
x:=a[(t+) shr ];
ans:=;
for i:= to t do
ans:=ans+abs(x-a[i]);
end
else begin
qsort(,n);
m:=;
c[]:=a[];
for i:= to t do
if a[i]<>a[i-] then
begin
inc(m);
c[m]:=a[i];
end;
mid:=a[t shr ];
for i:= to n do
ans:=ans+abs(b[i].x-mid)+abs(b[i].y-mid);
for i:= to n do
begin
b[i].x:=find(,m,b[i].x);
b[i].y:=find(,m,b[i].y);
add(,,m,,b[i].x,);
add(,,m,,b[i].y,);
end;
for i:= to n do
begin
add(,,m,,b[i].x,);
add(,,m,,b[i].y,);
add(,,m,,b[i].x,-);
add(,,m,,b[i].y,-);
min(ans,sum(,i*)+sum(,t-i*));
end;
end;
writeln(ans+s+n);
end.
4071
APIO2015题解的更多相关文章
- 【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)
[题解]P3645 [APIO2015]雅加达的摩天楼(分层图最短路) 感觉分层图是个很灵活的东西 直接连边的话,边数是\(O(n^2)\)的过不去 然而我们有一个优化的办法,可以建一个新图\(G=( ...
- 题解【luoguP3644 [APIO2015]八邻旁之桥】
题目链接 题解 家和公司在同侧 简单,直接预处理掉 若 \(k=1\) 取所有的居民的\(\frac{家坐标+公司坐标}{2}\)的所有坐标的正中间建一座桥,使所有居民到的距离最小. 实现方法:线段树 ...
- APIO2015简要题解
这场比赛当初是67(?)反正就是Cu滚粗了…… 先给个题目的传送门:http://wenku.baidu.com/link?url=mUxdsYomenU-e9SFVPacVtXysemiQA4KnP ...
- BZOJ4071 & 洛谷3644 & UOJ112:[APIO2015]巴邻旁之桥——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4071 https://www.luogu.org/problemnew/show/P3644 ht ...
- 贪心(qwq)习题题解
贪心(qwq)习题题解 SCOI 题解 [ SCOI2016 美味 ] 假设已经确定了前i位,那么答案ans一定属于一个区间. 从高位往低位贪心,每次区间查找是否存在使此位答案为1的值. 比如6位数确 ...
- 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap
[BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...
- 【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP
[BZOJ4069][Apio2015]巴厘岛的雕塑 Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 ...
- 【BZOJ4070】[Apio2015]雅加达的摩天楼 set+最短路
[BZOJ4070][Apio2015]雅加达的摩天楼 Description 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼 ...
- Luogu P3646 [APIO2015]巴厘岛的雕塑
深夜写题解系列,话说这题暑假的时候就在LOJ上做掉了,然后今天看到Luogu上有就去交了一下,发现没写过题解,赶紧来补一下 说句题外话APIO2015的题目好水啊 首先考虑按位取或的过程,很显然要从二 ...
随机推荐
- 微信小程序、应用号、订阅号、服务号、企业号小总结
微信小程序是现在微信推出的一个新的项目,但是很多人都不是很清楚微信小程序是怎么一回事,不明白到底怎样分别微信小程序和别的公众号.订阅号等的区别,那么让小编来给你介绍一下. 微信小程序目前是内侧阶段,是 ...
- Java 8 VM GC Tuning Guide Charter3-4
第三章 Generations One strength of the Java SE platform is that it shields the developer from the compl ...
- 一点ASP.NET MVC Html.Helper类的方法
一点ASP.NET MVC Html.Helper类 这里就只写一个Html.ActionLink()和Html.DropdownList(). Html.ActionLink()里有三个参数,第一个 ...
- ubuntu下修改ip重启系统ip不变
今天同学问我ubuntu下ip如何写死,我想起这周在公司我们队长也问过我,我就在这把我实验的方法说一下. 打开终端: sudo vim /etc/network/interfaces 然后按如下修改: ...
- Unity3dBug - OnEnable
最近 项目 因为 使用 active 代替 instantiate机制,很多时候 OnEnable 代理 OnStart. 然后发现一个 奇怪的 问题 void Awake() { Debug.Log ...
- What are Scopes?
scope is an object that refers to the application model. It is an execution context for expressions. ...
- POJ 2499 Binary Tree(二叉树,找规律)
题意:给一个这样的二叉树,每个节点用一对数(a,b)表示,根节点为(1,1).设父亲为(a,b),左儿子(a+b,b),右儿子(a,a+b). 给几组数据,(i,j),求从根节点到(i,j)节点需要向 ...
- POJ 1417 True Liars(种类并查集+dp背包问题)
题目大意: 一共有p1+p2个人,分成两组,一组p1,一组p2.给出N个条件,格式如下: x y yes表示x和y分到同一组,即同是好人或者同是坏人. x y no表示x和y分到不同组,一个为好人,一 ...
- MVC中SelectList和@Html.DropDownList("MainDuty_UserId","请选择")的运用
Models.Project model = projectdb.dbSet.SingleOrDefault(e => e.Project_ID == id); ViewB ...
- 查杀linux线程指令
工作中重启环境时常常出现内存溢出等等问题,往往需要查杀进程来帮助重启成功,下面就查杀线程的详细指令做下总结: 1.查找需要kill掉的线程: ps -elf|grep [线程关键信息] 比如: ...