分组赛讲课讲了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题解的更多相关文章

  1. 【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)

    [题解]P3645 [APIO2015]雅加达的摩天楼(分层图最短路) 感觉分层图是个很灵活的东西 直接连边的话,边数是\(O(n^2)\)的过不去 然而我们有一个优化的办法,可以建一个新图\(G=( ...

  2. 题解【luoguP3644 [APIO2015]八邻旁之桥】

    题目链接 题解 家和公司在同侧 简单,直接预处理掉 若 \(k=1\) 取所有的居民的\(\frac{家坐标+公司坐标}{2}\)的所有坐标的正中间建一座桥,使所有居民到的距离最小. 实现方法:线段树 ...

  3. APIO2015简要题解

    这场比赛当初是67(?)反正就是Cu滚粗了…… 先给个题目的传送门:http://wenku.baidu.com/link?url=mUxdsYomenU-e9SFVPacVtXysemiQA4KnP ...

  4. BZOJ4071 & 洛谷3644 & UOJ112:[APIO2015]巴邻旁之桥——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4071 https://www.luogu.org/problemnew/show/P3644 ht ...

  5. 贪心(qwq)习题题解

    贪心(qwq)习题题解 SCOI 题解 [ SCOI2016 美味 ] 假设已经确定了前i位,那么答案ans一定属于一个区间. 从高位往低位贪心,每次区间查找是否存在使此位答案为1的值. 比如6位数确 ...

  6. 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap

    [BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...

  7. 【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP

    [BZOJ4069][Apio2015]巴厘岛的雕塑 Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 ...

  8. 【BZOJ4070】[Apio2015]雅加达的摩天楼 set+最短路

    [BZOJ4070][Apio2015]雅加达的摩天楼 Description 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1.除了这 N 座摩天楼 ...

  9. Luogu P3646 [APIO2015]巴厘岛的雕塑

    深夜写题解系列,话说这题暑假的时候就在LOJ上做掉了,然后今天看到Luogu上有就去交了一下,发现没写过题解,赶紧来补一下 说句题外话APIO2015的题目好水啊 首先考虑按位取或的过程,很显然要从二 ...

随机推荐

  1. 微信小程序、应用号、订阅号、服务号、企业号小总结

    微信小程序是现在微信推出的一个新的项目,但是很多人都不是很清楚微信小程序是怎么一回事,不明白到底怎样分别微信小程序和别的公众号.订阅号等的区别,那么让小编来给你介绍一下. 微信小程序目前是内侧阶段,是 ...

  2. 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 ...

  3. 一点ASP.NET MVC Html.Helper类的方法

    一点ASP.NET MVC Html.Helper类 这里就只写一个Html.ActionLink()和Html.DropdownList(). Html.ActionLink()里有三个参数,第一个 ...

  4. ubuntu下修改ip重启系统ip不变

    今天同学问我ubuntu下ip如何写死,我想起这周在公司我们队长也问过我,我就在这把我实验的方法说一下. 打开终端: sudo vim /etc/network/interfaces 然后按如下修改: ...

  5. Unity3dBug - OnEnable

    最近 项目 因为 使用 active 代替 instantiate机制,很多时候 OnEnable 代理 OnStart. 然后发现一个 奇怪的 问题 void Awake() { Debug.Log ...

  6. What are Scopes?

    scope is an object that refers to the application model. It is an execution context for expressions. ...

  7. POJ 2499 Binary Tree(二叉树,找规律)

    题意:给一个这样的二叉树,每个节点用一对数(a,b)表示,根节点为(1,1).设父亲为(a,b),左儿子(a+b,b),右儿子(a,a+b). 给几组数据,(i,j),求从根节点到(i,j)节点需要向 ...

  8. POJ 1417 True Liars(种类并查集+dp背包问题)

    题目大意: 一共有p1+p2个人,分成两组,一组p1,一组p2.给出N个条件,格式如下: x y yes表示x和y分到同一组,即同是好人或者同是坏人. x y no表示x和y分到不同组,一个为好人,一 ...

  9. MVC中SelectList和@Html.DropDownList("MainDuty_UserId","请选择")的运用

    Models.Project model = projectdb.dbSet.SingleOrDefault(e => e.Project_ID == id);            ViewB ...

  10. 查杀linux线程指令

      工作中重启环境时常常出现内存溢出等等问题,往往需要查杀进程来帮助重启成功,下面就查杀线程的详细指令做下总结:   1.查找需要kill掉的线程: ps -elf|grep [线程关键信息] 比如: ...