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. Java 8 的内存结构

    Java8内存结构图 虚拟机内存与本地内存的区别 Java虚拟机在执行的时候会把管理的内存分配成不同的区域,这些区域被称为虚拟机内存,同时,对于虚拟机没有直接管理的物理内存,也有一定的利用,这些被利用 ...

  2. uniapp中scroll-view自定义滚动条

    注意事项 需在app.vue中添加如下,需要important /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 16upx!imp ...

  3. .NET 微服务——CI/CD(4):避坑和一点经验

    如果你看过之前几篇文章,应该已经Jenkins成功搭建了CICD环境,但是进入正式环境会有一些坑,不注意中招的话很难受,这里总结一下,避免重复消耗精力. 后门漏洞 Jenkins有后门,这是个老问题了 ...

  4. python中类对象、实例对象、类属性、实例属性、类方法、实例方法、静态方法

    类对象.类属性与实例对象.实例属性的区别 在Python中一切皆是对象,类是一个特殊的对象即类对象,描述类的属性称为类属性.类属性在内存中只有一份,在__init__外部定义. 通过类创建的对象称为实 ...

  5. 2018HPU暑期集训第四次积分训练赛 K - 方框 题解(图形打印)

    思路分析:题目已经明确透露了这道题的解法:就是画框.当 输入的边长  的话,就表示可以在内层继续嵌套一个方框.废话就不多说了,直接上代码吧! 代码如下: #include <iostream&g ...

  6. HttpRunner3的HTTP请求是怎么发出去的

    在HttpRunner3的示例代码中,发送HTTP请求的代码是这样写的: from httprunner import HttpRunner, Config, Step, RunRequest, Ru ...

  7. 【Java】重载与重写

    重载与重写 一.重载 定义 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可.同一个类.相同方法名,参数列表不同:参数个数不同,参数类型不同. Java的重载是可以包括 ...

  8. Android过时方法替代

    managedQuery替换为cursorLoader example: uri = data.getData(); String[] proj = {MediaStore.Images.Media. ...

  9. Web开发之HTTP协议

    HTTP响应消息 一个HTTP响应代表服务器向客户端回送的数据. 一个完整的HTTP响应包括如下内容: 一个状态行.若干消息头.以及响应正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用 ...

  10. 在Linux系统(centos7)中,安装VScode,并在VScode上编写HTML网页

    [实验目的] 在Linux系统中,搭建编写HTML网页的环境.在VS code官网上,下载VS code安装程序,进行安装.在VS code软件中编写HTML页面,并正确运行. [实验步骤] 1)   ...