JOISC 2020题解

被吊打了

先鸽着

JOI的本质:数 据 结 构 优 化 建 图

D1T1

https://loj.ac/problem/3271

爆零辣

显然的dp:设f[i][j][0/1]表示当前到i放了j个A当前是A/B 是否合法

发现对于每个i和0/1,合法的j是一个连续段

证明可以归纳,对于相邻两个位置的2A2B讨论大小,发现每种合法情况都能保证

代码: https://loj.ac/submission/770031

D1T2

https://loj.ac/problem/3272

正解还不太会,写了随机

代码:咕咕咕

D1T3

https://loj.ac/problem/3273

咕咕咕

D2T1

https://loj.ac/problem/3274

神奇交♂互题

把关系视作一个图,对于一个x只有三条边:x爱的,爱x的,和x同色的,把x和有边的一起询问时为1种颜色,没有边的是2种颜色

若x和x爱互相喜欢则视作只有一条同颜色边

若能求出这三种边,每次把x和其中的两个询问,如果只有一种颜色那么剩下的那个就是x喜欢的

找出喜欢的情况之后即可得出同颜色的

部分分23直接n^2找边,部分分4用二分找边

因为为什么要有性别限制,所以是个二分图

每次找一个最大独立集,加一个新的来判断整个集合

因为每个点只有最多三条边所以独立集大小>=|剩余S|/4

独立集内部没有边,所以只用考虑独立集和剩下的,以及剩下的之间的边

二分找前半部分,对剩下继续找独立集

由于每次大小减1/4所以次数不会很多

代码: https://loj.ac/submission/776947

D2T2

https://loj.ac/problem/3275

辣鸡题,难写的很

思路不难,一个由双向边组成的联通块操作后必然变成完全图,并且中途可能会引发连锁反应

一个点连一个块中的任意一点后都会变成连整个块中的所有点

在每个块上维护 点->当前块,当前块->其他块,其他块->当前块

每次合并两个块时,两个块连出去的边不会改变,连进来的边若只连了一边则要连另一边

启发式合并,同时再维护每个块 点->当前块的具体个数(因为不好把非法的删掉)

https://loj.ac/submission/773902

D2T3

https://loj.ac/problem/3276

这很AGC

请注意下文所指的是原2n的数组还是数组b

考虑从后往前放,每次放到数组b对应位置后若已放了就向前,最后停下来的位置就是最终的高度

证明考虑归纳,放了一个之后如果会产生冲突那么必然是存在三个相同高度的,这样才会影响到后面的操作,但显然这样不存在

(f[i][j])表示从后往前放了第i个,数组b的前j个已满,第j+1个未放,后面的未知

原来的题不好算方案,把两个相同高度的变为不同,最后除2^n

考虑第i-1个,设in表示[i,n+n]中保留的个数,out表示不保留的个数

①第i-1个不放:

(f[i][j]*(j-out)->f[i-1][j])

解释一下,第i-1个不放意味着必须要放到b中前j个里,这样才能把它弹掉

前j个中有2j个可以放,已经放了j个弹了out个,所以还有j-out个可以放

②第i-1个放:

1)放在>j+1个上

(f[i][j]->f[i-1][j])

注意具体是哪一个在之后考虑

2)放在j+1个上

(f[i][j]*(k+2)*g[k]*C_{in-j}^k->f[i-1][j+1+k])

枚举后面接上的长度k,其中[j+2,j+1+k]这一段中共有2k个,已经放了k个,所以可以放下后移到j+1的共有k+ j+1位置上的2个=k+2

由于第j+1个原本没有,所以这一段中必须有且只有k个放了

组合数不用减第j+1,因为没加进去

(g[k])表示在长度为k的数组中用每种2个共2k个高度放满的方案

(g[i][j])表示当前放了前i种,放了j个,那么上面的(g[k])等于现在的(g[k][k])

转移很显然,考虑第i+1种放012个,注意任何时候都有i>=j,因为最多只能把前i个放满

N^3 4s不慌

代码: https://loj.ac/submission/776301

D3T1

https://loj.ac/problem/3277

想了三种dp,前两种被毙掉,最后一种只能到n^3,结果不小心把n^2的过了

根据高度建笛卡尔树,如果有多个相同的就并列但是写的时候并不会笛卡尔树所以就用了rmq

那么一颗星星就等于树上的一条链,要找若干条链使其不相交且值最大

随便搞个dp,维护每条链下面的dp状态和,这个直接线段树

关于每条链的范围,找到每个点左右扩展的范围,按l小到大r大到小排序,发现刚好可以线性

log^2会被卡

代码: https://loj.ac/submission/772413

D3T2

https://loj.ac/problem/3278

咕咕咕

D3T3

http://uoj.ac/problem/509

两道题:

①A>=3 B>=0

从终点bfs分层,一次把每层的边按012染色,同层视作下一层

不断向上一层即可

②A=2 B>=6 保证是树

要求在3步以内判断出方向,剩下3步用来返回

一个简单的想法是按①一样01染色,如果初始点度数为1或>=3则可以轻松判断,一旦确定了方向就可以走到终点

问题是如果初始点在度数=2的点上就判不了

换一种思路,考虑按照某个串循环染色

首先这个串要满足循环之后不存在一条边使得其对称,并且长度<=6

所以考虑用001011来染,如果染到度数>=3的就硬点一个位置使得父亲边和儿子边颜色不同

朝一个方向走3步,如果走到了度数≠2的点就直接判断,否则根据经过的边的颜色来判断

3步加上首尾共5条边,00、11随便走,01强行走0,这样足以根据走出来的串判断是否反向

代码: http://uoj.ac/submission/389874

D4T1

https://loj.ac/problem/3280

我起了,直接(3h)切了,没什么好说的

一种很显然的方法是直接点分治,以分治中心为起点扩展,如果向下分治的时候一种颜色在两个子树里那在子树中就不能选

另一种也很显然的方法是直接树剖优化建图,每个颜色向其虚树连边,每个点向其颜色连边,之后tarjan缩点找无出度点

u->v意味着选了u就必须选v,所以是找无出度点

代码: https://loj.ac/submission/774376

抢到一血了

D4T2

https://loj.ac/problem/3281

辣鸡题答,弃了弃了

D4T3

https://loj.ac/problem/3282

很玄的dp

考虑已知了一个选择方案,怎样判断是否合法

假设方案乱序,如果起始方案l=1,终止方案r=n,相邻两个方案之间满足t先的清理后t后的可以把重叠部分扩散的清掉

方案乱序不如按r排序,排序后变成

(R_{ai}-L_{ai+1}+1>=|T_{ai}-T_{ai+1}|)

设f[i]表示以i结尾的答案,从i转移到j同理

(R_{i}-L_{j}+1>=|T_{i}-T_{j}|)

拆开绝对值之后因为有t的限制所以用主席树优化建图

因为不想大改所以卡空间卡到自闭

代码: https://loj.ac/submission/775765

原文地址:https://www.cnblogs.com/gmh77/p/12595250.html