ARC061(2020.7.10)

A

暴力 \(dfs\) 即可。

B

考虑统计以每个点为矩阵中心的答案,显然一个黑点只会影响周围九个黑点,使用 \(map\) 来记录这个值,每次修改修改一下答案数组即可。

C

首先是一个非常直接的做法,我们可以类似 \(dijkstra\) 的做法,使用堆来维护一个一个答案为第一关键字,种类为第二关键字的结构体,那么进入堆中的点将不会超过 \(n + m\) 个,每次再类似 \(dijkstra\) 的方法拓展即可。

另一种做法是这样的,因为我们只有在换乘的时候答案会 \(+1\) 那么我们可以考虑对同种类的道路连起来成为一条新路使得路径上的边权为 \(0\) 而进入这条道路的费用为 \(1\) 即可。不难发现我们可以将每个点拆乘 \(c\) (道路种数) 个点,分别表示在某个种类的新道上,从这个点向拆出来的点连一条边权为 \(1\) 的边表示进入这个种类的新路,对于原图中的每一条边,我们在其两端点对应种类拆出来的点连一条边权为 \(0\) 的边,那么这样就能达到我们最开始的想法,最后 \(\frac{dis_n}{2}\) 就是答案了,因为是双向边,进入和出来都会花费代价。但我们会发现点数是 \(O(nc)\) 级别的,但实际上边数很少是 \(O(n + m)\) 的,那么这就意味着很多点是没有用的,那么我们把这些没有用的点去掉剩下的点数就可以达到 \(O(n + m)\) 级别,于是复杂度就是 \(O((n + m) \log n)\) 了。

D

首先不难发现要让 \(A\) 赢需要 \(A\) 拿 \(n + 1\) 张牌,加上 \(A\) 最开始拿走的一张牌,意味着要抽出 \(A\) 号牌 \(n\) 张,因此在抽牌过程中最多抽 \(B\) 号牌 \(m\) 张,\(C\) 号牌 \(k\) 张。显然直接按照题目模拟并不好做,于是我们考虑这个抽牌的序列。不难发现一个抽牌序列(将所有牌抽完)会与摆放方案一一对应,于是我们考虑直接对抽牌序列进行计数即可。根据前面的条件我们一定要让这个序列有 \(n\) 个 \(A\),在序列中最多 \(m\) 个 \(B\),最多 \(k\) 个 \(C\).于是我们计数时可以考虑枚举 \(A\) 赢之前抽出了 \(i\) 张 \(B\),先往 \(n\) 个 \(A\) 中先插入 \(i\) 个 \(B\),这一部分的方案为 \(\dbinom{n + i - 1}{i}\),同理抽出 \(j\) 个 \(C\) 对答案的贡献是 \(\dbinom{n + i + j - 1}{j}\).最后剩下的牌可以任意排列即 \(3 ^ {m + k - i - j}\),那么最终的答案可以写成:

\[\sum\limits_{i = 0} ^ m \sum\limits_{j = 0} ^ k \dbinom{n + i - 1}{i} \dbinom{n + i + j - 1}{j} 3 ^ {m + k - i - j}
\]

中间有很多 \(i + j\) 的项,方便起见我们枚举 \(S = i + j\)

\[\sum\limits_{S = 0} ^ {m + k} 3 ^ {m + k - S} \sum\limits_{i = \max(0, S - k)} ^ m \dbinom{n + i - 1}{i} \dbinom{n + S - 1}{j}
\]

现在想办法把后面的东西化简,因为我们是从组合意义推来的组合数,因此再考虑组合意义不太可能,一个常见的套路是将组合数拆开看能否约去一些数。下面单独将后面那一坨拉出来看。

\[\sum\limits_{i = \max(0, S - k)} ^ m \frac{(n + i - 1)!}{i! (n - 1)!} \times \frac{(n + S - 1)!}{j! (n + i - 1)!}
\]

把 \((n + i - 1)!\) 约去

\[\sum\limits_{i = \max(0, S - k)} ^ m \frac{1}{i! (n - 1)!} \times \frac{(n + S - 1)!}{j!}
\]

可以发现下面三项加起来等于上面的数,根据一个常见的套路对于 \(\frac{(a + b + c)!}{a! b! c!}\) 这种柿子,我们可以将下面任意两项单独拉出来上下同乘两个数之和变成两个组合数相乘。比如可以将上面的式子画成这样:

\[\sum\limits_{i = \max(0, S - k)} ^ m \frac{S!}{i! j!} \times \frac{(n + S - 1)!}{S! (n - 1)!}
\]

\[\sum\limits_{i = \max(0, S - k)} ^ m \dbinom{S}{i} \times \dbinom{n + S - 1}{S}
\]

于是后面这个东西就之和 \(S\) 有关了,拉到前面去就变成了:

\[\sum\limits_{S = 0} ^ {m + k} 3 ^ {m + k - S} \dbinom{n + S - 1}{S} \sum\limits_{i = \max(0, S - k)} ^ m \dbinom{S}{i}
\]

可以发现后面相当于要求一行组合数的前缀和,这个东西是没办法快速计算的,但同时我们发现只需要查询两点的前缀和,其中一个右端点即在第 \(i\) 行前 \(m\) 个数的前缀和,而 \(m\) 是一个定值,可以考虑从之前的答案递推过来,令 \(f_i\) 为第 \(i\) 行前 \(m\) 个数的前缀和,再考虑组合数的递推公式 \(\dbinom{n}{m} = \dbinom{n - 1}{m - 1} + \dbinom{n - 1}{m}\)。将当前行的贡献算到上一行去,不难发现上一行的前 \(m - 1\) 个数要算 \(2\) 遍,最后一个数要算 \(1\) 遍,那么我们可以得到递推式 \(f_i = 2 \times f_{i - 1} - \dbinom{i - 1}{m}\).再考虑其左端点查询的位置,令 \(g_i\) 为第 \(i\) 行前 \(\max(0, S - k) - 1\) 的前缀和,不难发现最开始一端后面那个式子是从 \(0\) 开始枚举的,那么不需要减去左端点的值,而在 \(S > k\) 的时候,后面那一段就不再从 \(0\) 开始枚举了,看起来我们每次需要算每一行的前缀和位置不同,但实际上随着 \(S\) 的不断 \(+1\) 实际上 \(S - k\) 每次也只增加一位,也就意味着我们这一次计算的前缀和只和上一次有一位的区别,那么我们只需要手动加上这一位的答案即可,类似于前面的递推,可以得到 \(g_i = 2 \times g_{i - 1} + \dbinom{i - 1}{i - k - 1}\).于是枚举 \(S\) 后面那个东西就可以 \(O(1)\) 算了。

Atcoder ARC-061的更多相关文章

  1. 【题解】Atcoder ARC#90 F-Number of Digits

    Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...

  2. AtCoder ARC 076E - Connected?

    传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...

  3. AtCoder ARC 076D - Built?

    传送门:http://arc076.contest.atcoder.jp/tasks/arc076_b 本题是一个图论问题——Manhattan距离最小生成树(MST). 在一个平面网格上有n个格点, ...

  4. AtCoder ARC 082E - ConvexScore

    传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...

  5. Atcoder ARC 082C/D

    C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...

  6. 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

    题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...

  7. 【题解】Atcoder ARC#96 F-Sweet Alchemy

    首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...

  8. AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision

    题目传送门:ARC090E. 题意简述: 给定一张有 \(N\) 个点 \(M\) 条边的无向图.每条边有相应的边权,边权是正整数. 小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则 ...

  9. 【题解】Atcoder ARC#67 F-Yakiniku Restaurants

    觉得我的解法好简单,好优美啊QAQ 首先想想暴力怎么办.暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值.这样的复杂度是 \(O(n ^{2} m)\) 的.但是这样明显能够感觉到我们重复 ...

  10. 【题解】Atcoder ARC#85 E-MUL

    ……没啥可说的.最大权闭合子图,跑下dinic就好了…… #include <bits/stdc++.h> using namespace std; #define maxn 500000 ...

随机推荐

  1. 知识增强的预训练语言模型系列之ERNIE:如何为预训练语言模型注入知识

    NLP论文解读 |杨健 论文标题: ERNIE:Enhanced Language Representation with Informative Entities 收录会议:ACL 论文链接: ht ...

  2. oracle中connect by prior的使用

    作用 connect by主要用于父子,祖孙,上下级等层级关系的查询 语法 { CONNECT BY [ NOCYCLE ] condition [AND condition]... [ START ...

  3. MA8621带SD读卡的USB 2.0高速3端口HUB方案芯片|MA8621中文规格书|USB 2.0方案

    MA8621说明 MA8621是USB 2.0高速3端口集线器的高性能解决方案,带有SD卡控制器,完全符合通用串行总线规范2.0.控制器继承了先进的串行接口技术,当3个DS(下游)端口同时工作时,功耗 ...

  4. node.js安装及环境配置超详细教程【Windows系统安装包方式】

    文章目录 Step1:下载安装包 Step2:安装程序 Step3:查看 Step4:环境配置 最后补充: Step1:下载安装包 https://nodejs.org/zh-cn/download/ ...

  5. 编写Java程序,随机给定一个数字猜大小

    返回本章节 返回作业目录 需求说明: 由系统随机生成一个1~100之间的整数. 通过控制台一直输入一个整数,比较该数与系统随机生成的那个数,如果大就输出"猜大了.",继续输入:如果 ...

  6. Roslyn+T4+EnvDTE项目完全自动化(3) ——生成c++代码

    C++语法复杂,写一个示例通过T4可生成c++代码 需求:数据库,生成c++增,删,改,查代码 数据生成c++类,包含所有字段 自动识别数据的主键Key 查询生成赋值类字段,类型转换 通过类自动生成s ...

  7. XML解析和创建的JAXB方式

    1.说明 JAXB是Java Architecture for XML Binding, 即用于XML绑定的Java体系结构, JAXB作为JDK的一部分, 能便捷地将Java对象与XML进行相互转换 ...

  8. 初识python:time 模版

    语法及示例代码如下: import time # time 时间戳,1970年到当前时间的秒数 print('time:',time.time()) # sleep 延时.睡眠(s) print('s ...

  9. 建造者模式(python)

    建造者模式将复杂对象的构建与其表示分离.建造者模式主要有两个参与者:建造者(builder)和指挥者(director) 来自为知笔记(Wiz)

  10. 【Warrior刷题笔记】143.重排链表 【线性化 || 双指针+翻转链表+链表合并】详细注释

    题目一 力扣143.重排链表 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reorder-list/ 1.描述 给定一个单链表L的头节点he ...