JSOI的题质量很高……

精准预测(2-SAT、拓扑排序、bitset)

不难发现两个条件都可以用经典的2-SAT连边方式连边,考虑如何加入时间的限制。对于第\(x\)个人在\(t\)时刻的状态是生/死建点\((x,0/1,t)\),连上边\((x , 0 , t) \rightarrow (x , 0 , t-1)\)和\((x,1,t) \rightarrow (x , 1 , t+1)\)然后用2-SAT方式连边,就可以加入时间限制了。

上面的点数实在是太多了,一种朴素的想法是把所有2-SAT边连接的点拿出来建图。这样总点数是\(4m\)的,在LOJ上可以跑过,但是在Luogu上过不去……

还有一种相对更优秀的建图:对于2-SAT中的边\((x,y)\),如果\(y\)在2-SAT边中没有出边,那么将\(x\)连向\(y\)的后继和将\(x\)连向\(y\)是等价的。所以我们可以只拿出所有2-SAT边的出点和所有\((x,0/1,T+1)\),这样总点数就是\(2n+2m\)的。

不难发现我们连出来的图是一个拓扑图(生状态之间是一个拓扑图、死状态之间是一个拓扑图、跨越生死的边均是生连向死),所以我们的问题变成了对于每一个\((x,0,T+1)\)求出它能够到达的所有\((y,1,T+1)\)的状态数。在反图上拓扑排序+bitset。bitset开不下空间,于是分批做拓扑排序即可,复杂度不变。

注意可能存在一个人生连向死的情况,这个要特殊判断一下。

如果过不去开O3试一下……

代码

神经网络(树形DP、容斥、生成函数)

这似乎是某道模拟赛题……

题目等价于:每一次可以在一棵树上选一条链(链上的点和之前经过的点无交),然后再在其他任意一棵树上选,问选到所有点的方案数

把这道题分为两个部分:将一棵树分为若干不相交的链、将这些链安排顺序使得不存在两条相邻的链来自同一棵树。

因为第二部分的方案数只和第一部分中每棵树划分出的链的条数有关,所以要求对于每一个\(j\),将当前树划分为\(j\)条链的方案数。不难想到一个树形DP:设\(f_{i,j,0/1/2}\)表示\(i\)及其子树中共有\(j\)条链,\(i\)点向儿子连出\(0/1/2\)条边的方案总数,转移考虑儿子和当前点的链是否合并。

值得注意的是:\(1\)个点也是一条链;对于长度\(>1\)的链,它对答案的贡献为\(2\),因为对于链的两个端点\(AB\),可以\(A\)进\(B\)出,也可以\(B\)进\(A\)出,在DP的时候需要乘上这个系数。

然后考虑第二部分。设第一部分求出来的答案为\(f_{i,j}\)表示将第\(i\)棵树分成\(j\)段的方案数\(\times j!\),因为链有序。接下来只需要考虑相邻链不来自同一棵树的方案。

先考虑序列上的问题,我们选择指数型生成函数求解。假设将第\(i\)棵树划分成\(k\)条链,那么在序列上会有\(k-1\)个空。容斥有多少个空在序列合并后不存在,不难得到这一项的值为\(f_{i,k} \sum\limits_{j=1}^k (-1)^{(k-j)} \binom{k-1}{j-1} \frac{x^j}{j!}\),那么这一棵树的生成函数就是\(\sum\limits_{k=1}^{k_i} f_{i,k} \sum\limits_{j=1}^k (-1)^{(k-j)} \binom{k-1}{j-1} \frac{x^j}{j!}\)

然后考虑环上。我们选出一棵树作为基准树,即断环成链之后,序列起始的一条链一定来自这棵树。那么其他树的生成函数不变,这棵树由于第一条链的位置确定,所以生成函数变为\(\sum\limits_{k=1}^{k_i} \frac{f_{i,k}}{k} \sum\limits_{j=1}^k (-1)^{(k-j)} \binom{k-1}{j-1} \frac{x^{j-1}}{(j-1)!}\),在\(f_{i,k}\)处除\(k\)的原因是将\(i\)树划分为\(k\)条链后这\(k\)条链都可以作为序列的起始位置。

还有一个限制是基准树的第一条链和最后一条链之间不能相接。所以基准树的生成函数还需要减掉\(\sum\limits_{k=1}^{k_i} \frac{f_{i,k}}{k} \sum\limits_{j=1}^k (-1)^{(k-j)} \binom{k-1}{j-1} \frac{x^{j-2}}{(j-2)!}\)。

最后暴力把这些函数卷积就可以得到答案。复杂度\(O(n^2)\)。

代码

节日庆典(最小表示法、Z-algorithm)

我们要求每一个前缀的最小表示法,然后这道题就跟最小表示法没什么关系了。我们使用增量法求解,也就是每一次加入一个字符,然后在新的串上快速求解。

对于当前正在考虑的前缀\(s[1,l]\)的两个后缀\(i,j(i < j \leq l)\),若\(LCP(suf_i , suf_j) < l - j + 1\),那么后缀较大的那个位置不可能作为最小表示法的位置;如果\(LCP(suf_i , suf_j) \geq l - j + 1\),那么两个位置都有可能作为最小表示法的位置。我们维护集合\(S\)满足\(\forall a,b \in S , a < b , LCP(suf_a , suf_b) \geq l - b + 1\),就可以将答案锁定在\(S\)内。但是\(S\)的元素个数可能仍然很多,所以仍需优化。

考虑对于\(S\)中的两个数\(a,b\)满足\(l-b+1 < l-a+1 < 2(l-b+1)\)。由于\(s[b,l]\)是\(s[a,l]\)的前缀、是\(s[a,l]\)的后缀,也就是\(s[a,l]\)的长度\(> \frac{l-a+1}{2}\)的border。这意味着\(s[a,l]\)有一个长度为\(b-a\)的周期,设这个周期串为\(T=s[a,b-1]\)。这同时意味着\(s[a,l]\)有一个比\(l-b+1\)更短的border​,记作\(s[c,l]\),不难发现\(c\)的一个可行值为\(2b-a\)。

因为串循环相当于在当前串的末尾插入当前串开头对应的字符,所以考虑在\(s[a,l],s[b,l],s[c,l]\)之后加入字符会得到怎样的解。如果加入的字符\(x = T[0]\),令\(T = T[1,l] + T[0]\),继续往后做;如果\(x < T[0]\),则\(s[c,l]+x < s[b,l]+x < s[a,l] + x\),选择\(c\)更优;如果\(x > T[0]\),则\(s[c,l]+x > s[b,l]+x > s[a,l] + x\),选择\(a\)更优;如果匹配到最后都没有匹配出三者的大小关系,因为\(a<b<c\),所以选择\(a\)更优。这意味着\(b\)无论如何不可能最优,可以直接把\(b\)删掉。

按照上面的叙述操作之后,\(\forall a,b \in S , a<b \rightarrow l - a + 1 \geq 2(l - b + 1)\),那么\(S\)的元素个数只有\(O(logn)\)个。而我们可以在增量的时候方便地维护集合\(S\)。

接下来考虑如何通过\(S\)求出答案。我们需要做的就是对于两个位置\(a,b(a<b \leq l)\)求出两种循环表示的串的字典序大小。从\(a\)开始的循环串分为\(s[a,l]\)和\(s[1,a-1]\),从\(b\)开始的循环串分为了\(s[b,l]\)和\(s[1,b-1]\),而由\(S\)的定义可知\(s[a,a+l-b] = s[b,l]\),所以我们只需比较\(s[a+l-b+1,l]\)与\(s[1,b-a]\)之间的关系、\(s[1,a-1]\)与\(s[b-a+1,b-1]\)之间的关系,也就是求出\(LCP(suf_1,suf_{a+l-b+1})\)和\(LCP(suf_1,suf_{b-a+1})\)。

注意到上面的LCP的计算都和原串有关,所以可以在\(O(n)\)时间内用Z-algorithm求出每一个后缀和原串的LCP,就可以快速比较两个位置。

复杂度是不满的\(O(nlogn)\)。

代码

JSOI2019 Round2的更多相关文章

  1. JSOI2019 Round2 极限生还

    江苏省省队一共13个名额,去掉女生名额, 按1/3校内限制,我们南外只有4个名额, 在noip爆炸(占比35%),省选一轮爆炸(占比40%),(此时蒟蒻在校内排不进前10...) 总算在省选二轮(占比 ...

  2. 【ContestHunter】【弱省胡策】【Round2】

    官方题解:http://wyfcyx.is-programmer.com/posts/95490.html A 目前只会30分的暴力……DP好像很神的样子0.0(听说可以多次随机强行算? //Roun ...

  3. Loj #3102. 「JSOI2019」神经网络

    Loj #3102. 「JSOI2019」神经网络 题目背景 火星探险队发现,火星人的思维方式与人类非常不同,是因为他们拥有与人类很不一样的神经网络结构.为了更好地理解火星人的行为模式,JYY 对小镇 ...

  4. 【LOJ】#3103. 「JSOI2019」节日庆典

    LOJ#3103. 「JSOI2019」节日庆典 能当最小位置的值一定是一个最小后缀,而有用的最小后缀不超过\(\log n\)个 为什么不超过\(\log n\)个,看了一下zsy的博客.. 假如\ ...

  5. 【LOJ】#3102. 「JSOI2019」神经网络

    LOJ#3102. 「JSOI2019」神经网络 首先我们容易发现就是把树拆成若干条链,然后要求这些链排在一个环上,同一棵树的链不相邻 把树拆成链可以用一个简单(但是需要复杂的分类讨论)的树背包实现 ...

  6. 【LOJ】#3101. 「JSOI2019」精准预测

    LOJ#3101. 「JSOI2019」精准预测 设0是生,1是死,按2-sat连边那么第一种情况是\((t,x,1) \rightarrow (t + 1,y,1)\),\((t + 1,y, 0) ...

  7. [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset)

    [LOJ 3101] [Luogu 5332] [JSOI2019]精准预测(2-SAT+拓扑排序+bitset) 题面 题面较长,略 分析 首先,发现火星人只有死和活两种状态,考虑2-SAT 建图 ...

  8. 【JSOI2019】精准预测(2-SAT & bitset)

    Description 现有一台预测机,可以预测当前 \(n\) 个人在 \(T\) 个时刻内的生死关系.关系有两种: \(\texttt{0 t x y}\):如果 \(t\) 时刻 \(x\) 死 ...

  9. [JSOI2019]节日庆典 做题心得

    [JSOI2019]节日庆典 做题心得 一个性质有趣的字符串题 这要是在考场上我肯定做不出来吧 一开始还以为要 SAM 什么的暴力搞,没想到只用到了 \(Z\) 函数 -- 也是我生疏了罢 (学了啥忘 ...

随机推荐

  1. 数据结构---公交线路提示系统05(内附读取表格+迪杰斯特拉算法Java代码)

    今天做的最多的事情就是纠错了,通过添加输出语句判断错误来源: 找到错误来源: wb = new XSSFWorkbook(input);//语句创建错误 网上查询发现是jar包的问题: 下图为poi的 ...

  2. es6学习3:promise

    promise含义: 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Pro ...

  3. TypeScript之Https通信

    NetWorkRequest.ts(源代码如下) import * as https from "https"; import * as vscode from 'vscode'; ...

  4. 为什么集合类没有实现Cloneable和Serializable接口

    为什么集合类没有实现Cloneable和Serializable接口? 答:克隆(cloning)或者序列化(serialization)的语义和含义是跟具体的实现相关的.因此应该由集合类的具体实现类 ...

  5. 【数值分析】Python实现Lagrange插值

    一直想把这几个插值公式用代码实现一下,今天闲着没事,尝试尝试. 先从最简单的拉格朗日插值开始!关于拉格朗日插值公式的基础知识就不赘述,百度上一搜一大堆. 基本思路是首先从文件读入给出的样本点,根据输入 ...

  6. 正向代理 & 反向代理 & 透明代理

    正向代理(Forward Proxy) 概述 一般情况下,如果没有特别说明,代理技术默认说的是正向代理技术.关于正向代理的概念如下: 正 向代理(forward)是一个位于客户端[用户A]和原始服务器 ...

  7. 第10组 Alpha冲刺(5/6)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 学习调用中国天气网API,接近实现天气推送功能 对天气推送的形式进行讨论及重确 ...

  8. DATEADD (Transact-SQL)

    DATEADD (Transact-SQL) This function adds a specified number value (as a signed integer) to a specif ...

  9. ggplot常见语法汇总查询

    主图 散点图 柱状图 折线图 小提琴图 点图 进化树 圈图 Alluvial图 Sankey Diagram plot(getSankey(colData(muraro)$cell_type1, mu ...

  10. MySQL中的比较操作符<=>

    对于=操作符,两个值被比较,结果是0(不相等)或者1(相等). 比较操作符<=>表示NULL安全的等价.这个比较操作符执行等价比较,和=操作符类似,但是如果两个操作数都是NULL,会返回1 ...