JSOI2009 题解

  • 游戏

    容易想到对棋盘黑白染色后,一个人只会经过一种颜色。进一步地,黑白染色后,原图变成一张二分图。考察其中的一个最大匹配,如果起点放在匹配点上,那么 Y 可以每次都走匹配边,A只能找非匹配边走,于是 A 必败(这里的必败指只用当前指定的最大匹配的前提下);如果起点放在非匹配点上,那么 Y 要么走不出第一步,要么第一步走到一个匹配点上,于是 A 就可以仿照上面的策略,必胜。

    综合来看,只要 A 选的起点是某个最大匹配的非匹配点,A 就必胜。

    所以先用 Dinic 随便跑出一个最大匹配,如果是完美匹配,那么 A 必败。否则,其中的非匹配点一定是合法点。对于所有合法点 \(u\),其通过一条非匹配边走到点 \(v\),如果 \(v\) 有匹配点 \(w\) ,那么 \(w\) 一定也是合法点,因为可以让 \((u,v)\) 变成匹配边,让 \((v,w)\) 变成非匹配边。显然,这样找一定能找遍所有合法点,而每个合法点只会访问一次,所以时间复杂度是线性的。总时间复杂度是 Dinic 的时间复杂度 \(\mathcal{O}(nm\sqrt{nm})\)

  • 有趣的游戏

    经典题。建立 AC 自动机后,设 \(f_{i,u}\) 为第 \(i\) 轮走到节点 \(u\) 的概率,那么 \(\sum_{i=0}^{\infty} f_{i,p_j}\) 即为第 \(j\) 个人获胜的概率。令 \(x_u=\sum_{i=0}^{\infty}f_{i,u}\) ,那么容易列出 \(N\) 个方程(\(N\) 是 AC 自动机节点数),高斯消元即可,时间复杂度 \(\mathcal{O}(n^3l^3+nml)\)

  • 球队收益

    先假设所有球队都输了,这样子就可以理解成每场比赛安排一个胜者,胜者会产生额外的花费,并且由于 \(D_i\le C_i\) ,任何球队被安排获胜后,下一次获胜的花费一定不小于这次的花费。于是考虑建立费用流模型:

    • 每场比赛建点 \(p\) ,连边 \((S,p,1,0)\)

    • 每个球队建点 \(x\) ,连其参与的比赛次数条边,假设第 \(i\) 次获胜的花费是 \(v_i\) ,那么连边 \((x,T,1,v_i)\)

    • 比赛 \(p\) 参与的队伍是 \(x\)\(y\) ,连边 \((p,x,1,0)\)\((p,y,1,0)\)

    跑最小费用最大流即可。

  • Count

    二维树状数组板子题,开 \(c\) 个二维树状数组即可过。可以通过离线对每个权值单独操作做到只开一个二维树状数组。如果空间要求更紧的话可以 cdq 分治做到只开一个一般的树状数组,因为这个问题本质上是三维数点。时间复杂度 \(\mathcal{O}(c+(nm+q)\log n\log m)\)

  • 等差数列

    修改和询问都是在等差数列的基础上的,考虑对原序列进行差分变换后,修改变成了常数次区间加,而查询变成了可以删掉若干个区间的数,要求剩余的所有极长的没被删除的连续段的所有数相等,问最少的删除个数。这个问题的信息是容易区间合并的,只需要维护一个区间左右端点是否删除的答案以及左右端点的数是多少即可,因为容易证明合并区间 \([l_1,r_1]\)\([l_2,r_2]\) 时,如果 \(r_1\)\(l_2\) 的值不同,那么存在一个最优方案使得 \(r_1\)\(l_2\) 恰好有一个被删除。线段树维护即可,时间复杂度 \(\mathcal{O}(n+q\log n)\)

  • 密码

    第一问是比较经典的套路,建立 AC 自动机后跑状压 dp 即可。至于第二问,可以直接记录 dp 转移,最后的时候倒着搜一下就好了,但这种方法可能要卡一下空间。也可以直接爆搜。时间复杂度 \(\mathcal{O}((\sigma+c)2^nL\sum|S|),c=42\)

  • 火星藏宝图

    容易想到一个暴力 dp :\(f_i\) 表示走到第 \(i\) 座岛的最大收益。暴力转移就可以做到 \(\mathcal{O}(n^2)\) 。但观察到一个性质:对于同一列的所有岛屿,肯定从最下面的岛屿转移过来。所以单次转移优化到 \(\mathcal{O}(m)\) ,总复杂度 \(\mathcal{O}(nm)\) ,已经可以通过。把状态改成 \(f_{i,j}\) 表示走到 \((i,j)\) 的最大收益,转移式子明显可以斜率优化,时间复杂度 \(\mathcal{O}(m^2)\)

  • 去括号

    模拟就行,做到 \(\mathcal{O}(|S|^2)\) 是容易的。 \(\mathcal{O}(|S|)\) 也是不难的,从外到内去括号就可以实现,仁者见仁,智者见智。

  • 面试的考验

    此题和 CF765F Souvenirs 基本一样,只多了两个数不能相等的限制,和数据随机的特性。

    方法一:离线,只考虑 \(a_j>a_i(j<i)\) 的情况,另一种情况翻转值域再做一次即可。从左到右考虑每个数被选且是右边的数时的贡献,假设当前在 \(i\) , 先在权值线段树上找到左边第一个比 \(a_i\) 最大的数 \(a_j\),它会对之后满足 \(l\le j\) 的询问产生贡献,再开一个树状数组维护一下即可。再考虑 \(a_j\) 左边的数,如果继续暴力做的话复杂度肯定有问题,但是考虑到如果下一个找的数 \(a_j-a_k\le a_k-a_i\) ,那么 \(k\) 一定不优,所以下一个数 \(a_k\) 满足 \(a_j-a_k>a_k-a_i\) ,所以 \(a_j-a_i>2(a_k-a_i)\) ,差值每次减半,最多查 \(\mathcal{O}(\log V)\) 次,时间复杂度 \(\mathcal{O}(n\log n\log V+q\log n)\) 。如果强制在线的话把树状数组换成主席树就好了。

    方法二:离线,考虑枚举全局最优解 \((a,b)\),如果询问 \((l,r)\) 满足 \(l\le a < b\le r\) ,那么就找到该询问的答案,直接把它删除即可。由于数据随机,一个询问满足条件的概率大概是 \(\frac{1}{6}\) (但是随着算法的进行,概率会逐渐减小)。接着考察全局次优解,第三优解... 最后暴力处理没有算出来的询问即可。

    方法三:还是离线,并且和方法一类似。假设当前在 \(i\) ,从左到右贪心地找到一个严格大于 \(a_i\) 且单调递增的子序列,容易证明能跟 \(a_i\) 产生贡献的数一定都在这里面。由于数据随机,这个子序列长度的期望容易算出来是 \(\mathcal{O}(\log n)\) 的。还是用权值线段树加速查找的过程,用树状数组维护答案即可。时间复杂度 \(\mathcal{O}(n\log^2n+q\log n)\)

    方法一和方法三看似差不多,本质上的差异是方法一是按值从大到小找 \(a_j\) 的,这样找下一个数时就能产生额外的限制,从而达到不依赖随机化而加速的目的。

  • 瓶子和燃料

    根据裴蜀定理,用 \(\{V_i\}\) 里的瓶子得到的答案是 \(\gcd V_i\) ,所以就是求从 \(n\) 个数里选 \(k\) 个数,使得它们的 \(\gcd\) 最大。算一下每个数是多少个数的约数,取最大一个合法的即可,时间复杂度 \(\mathcal{O}(n\sqrt v(\log n+\log v))\) ,卡不满,随便跑。

  • 电子字典

    建 Trie 树后 dfs 就好了,注意去重即可。

posted @ 2023-01-05 16:18  Sword_K  阅读(84)  评论(0)    收藏  举报