day4

简单图论与构造

A

考虑把权值为 2 的点看作给权值为 1 的点加一,

所以整个问题被拆成了两个部分:构造树和给节点加一

事实上,在第一部分时我们将树构造的尽量平衡是有好处,这个结论在第二个步骤中会得到证明

构造:

Process DFS(father,ch,u,size):
if size==0 then return
son[father][ch]=u
size=size-1
DFS(u,0,v,size/2)
DFS(u,1,v',size-size/2)

然后考虑分配加一的点数,具体的需要注意到:

给一个节点加一对子树内的平衡性是不产生影响的

所以考虑从上往下贪心的分配,每次给自己加一后优先给小的子树分配一个

然后再对半分,而由于树是尽量平衡的,所以每个节点和自己的兄弟的差至多是一,是满足这个贪心的分配结构的

B

递归构造,假如某个节点 u 的所有的子树 vi 都已经构造出了答案,

对于每个儿子 v 的答案为 array[v]={vstate1,vstate2,vstate3...} ,那么考虑多元组:

i,j,k,...=(vstatei(1),vstatej(2),vstate3(3),...)

经历如下过程:

i: 1 -> x
then j: 1 -> 2
i: x -> 1
then j: 2 -> 3
...
then j: y-1 -> y
then k: 1 -> 2
i: 1 -> x
then j: y -> y-1
...

即可

len(array[u]=len(array[vi])

C

转化一下题意,把每次给出来的二元组看成边,那么就是要给边配对,使得配对的两条边是共用顶点的

那么我们先考虑联通图的情形,

如果是一棵树,我们考虑归纳构造:

在以 u 为根的子树内的边相互匹配,那么如果子树里有偶数个边,那么一定存在一种恰好匹配完的方式

如果有奇数个边,那么一定有一种是使得剩下的那个边是 u 连向自己的父亲的,然后放到父亲那里继续匹配(u 的兄弟节点之间匹配)

图的情况是一致的,因为在 DFS 生成树上,非树边一定是反祖边,一起放到父亲那里考虑即可

D

对于前 n2 份作业,我们钦定他们谁都不能打爆谁,对于后 n2 份作业,我们钦定靠前的一定能打爆靠后的,并且这后 n2 份作业每一篇都能打败前 n2 份作业 ,容易发现,这样的能够构造出

n2(1+n2)n22=n316

次的比对,符合要求

E

简单等积变形即可

首先可以知道 k|n×m×2 ,然后设 x=n×m×2k

假如 nx ,那么直接令底为 x ,令高为 1

假如 n<x ,那么令底为 n ,然后就可以得知高为 xn ,但是这个可能是一个小数,因此就需要用等积变形把它变成一个整数的坐标。现在三角形的底是平行于坐标轴的,如下:

然后把 (0,0) 抬高一个点,这样子这个三角形的底边就是倾斜的了,如下

接着右上角的那一个点就可以在灰线上乱滑了,由于斜线的斜率为 1n ,就意味着这个点每向 x 轴挪一个整点,纵坐标就增加了 1n 。就这样可以把 y 坐标调整到 xn ,如下

其中 t 就是向左滑行的量,t=(xnxn)×n,显然这个 t 是小于 n 的,因为 xx<1 ,然后这个三角形的面积就是 x2 的,和题目要求一致。

F

考虑存在偶数边长的情形,那么如下构造

<--even-->
1111111111
1*1*1*1*11
11+1*1+1+1
1*1*1*1*11
1111111111

如果长和宽都是奇数的情形,如果还像上面那样构造,就会出现 1111 的情形

这个时候考虑把某个乘号换成加号即可

1 1 1 1 1 1 1 1 1
1 * 1 * 1 * 1 * 1
1 1 + 1 * 1 * 1 1
1 * 1 * 1 * 1 * 1
1 1 * 1 + 1 * 1 1
1 * 1 * 1 * 1 * 1
1 1 * 1 * 1 + 1 1
1 * 1 * 1 * 1 * 1
1 1 1 1 1 1 1 1 1

G

简单网络流,就是二分图匹配,考虑每个左边的点向右边的自己的因子连边权为一边,然后右边的每个数向超级汇点连一个边权为一的边即可

H

最小割,把每个 x 节点拆成三个点 x1,x2,x3 然后连边:

(x1)1(x2)\infin(x3)

对于所有的指向 x 的边,通过如下方式确定其终点:

  • 如果检查站设置在 x ,那么这个边的指向 x1

  • 否则这个边指向 x3x1

对于所有从 x 出发的边,通过如下方式确定其起点:

  • 如果检查站设置在 x ,那么这个边的起点是 x2
  • 否则这个边的起点是 x3

对于每个边,我们有唯一的方式确定了其起点和终点,所以图是确定的(定义是良性的)
然后跑最小割即可。另外注意算法的常数,传说有人的 dinic 被卡了

I

先考虑一个强连通分量里的情形,一个强连通分量能在自身内无限循环的充要条件是

  • 在该强连通分量内存在一条边权和不为零的回路

所以可以把这个强连通分量抽出来跑 dfs 生成树即可

然后显然一个强连通分量能无限循环的条件为以下二者之一或者二者全部:

  • 这个强连通分量能自身无限循环
  • 这个强连通分量能去到无限循环的强连通分量

所以简单跑一下 tarjan 即可

J

我们把每段圆弧看作向量:

a=[(1)r(2)r]

那么要做的就是给每个向量的两个分量安排正负使得所有向量之和为零向量

然后先看要求光滑连接这个条件,实际上就是要求 n 是偶数,因为你总是以正负交替的方式来安排各个圆弧的方向

证明思路:

在变换的条件下,拐弯方向的差的奇偶性不改变,就意味着无论怎么平移都没有用,所以每个方向的边要有奇数个才能行:

存在方案使得:1.正的圆弧的和=ri2

比如说,现在x的分量的染色方法确定了

x: ++++--+++++--

y: +++-++---++--

上面有一种染色的方法,同时下面有另外一种染色的方法,并且这两种方法不能通过全体正号变成负号,负号变成正号来得到

我们观察得到,染色的方案总是偶数的:

因为染色方案是配对的

至少有4种染色的方案,

-> 有四种选取r的方案使得选中的 r 的和为 r2

dp[0/1,i,x] 表示前i个圆弧,选出来了奇数/偶数个,然后总和为 x 的方案有多少:

0,1,2,3,4

dp[0/1,i,x]=min(dp[0/1,i,x],4)

dp[1,n,sumr/2]=4 yes

否则 no

那么实际上就是要在这 nr 中选取若干个使得:

iri=ri2

然后你要两个分量都有的选,所以总共要有至少 4 种不同的选法才行,所以就是背包计数

K

分层图+最短路即可

ex

之前数据结构专题的A题的矩阵做法没有假,但是需要修改一下,因为问题是矩阵只能用来判断是否匹配但是没办法判断是否合法,比如这种情况)(,][,}{等,所以我们考虑先判断一个括号段是否合法,如果合法了我们才求出其矩阵的乘积即可,然后对着矩阵乘积来进行哈希

dp[i] 表示第i个括号匹配到谁(或者是被哪个不匹配的括号给阻断了)

(l,r) minlir(dp[i])r

posted @   chx#XCPC  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示