AtCoder Beginner Contest 248(A~G)

ABC248A Lacked Number

一个看上去比较高端的做法:设 \(w=0\oplus 1\oplus2\oplus\cdots \oplus 9\),其中 \(\oplus\) 表示异或。用 \(w\) 去异或字符串中的每个数即可。

这是因为 \(x\oplus x=0\),出现过的数刚好会被消掉,最后只剩下一个没有出现的数。AC Code

ABC248B Slimes

依照题意模拟即可。AC Code

ABC248C Dice Sum

典中典背包DP。我还写过题解:Link

然后官方题解里面说可以多项式优化,其实也挺板子的。。

AC Code

ABC248D Range Count Query

不会真的有人写莫队吧

考虑开 \(n\)vector,第 \(i\)vector 按升序存一下满足 \(a_x=i\) 的所有 \(x\),也就是序列中 \(=i\) 的所有数的下标。

那么查询 \([l,r]\)\(=k\) 的元素个数时,只需要在第 \(k\)vector 内二分出来第一个和最后一个位于 \([l,r]\) 内的数所处的位置,这两个数在这个 vector 中的距离就是答案。复杂度 \(O(n+q\log n)\)AC Code

ABC248E K-colinear Line

考虑枚举两个点 \(i,j\),然后判断它们是否经过了 \(\ge k\) 个点。

一共有 \(O(n^2)\) 个点对,判断在某条直线上的点数可以直接 \(O(n)\) 做,那么复杂度就是 \(O(n^3)\)

为了防止算重,需要处理出来每条直线的斜率与截距扔进 map 里面。

我一开始为了避免精度误差直接当做分数存进了 map 里,然后发现巨难写。。

写了半小时交了一发之后还 wa 了。。。心态爆炸.jpg

突然我一拍脑袋,如果有 \(x\) 个点共线,那么我们会枚举这一条直线 \(\dfrac{x(x-1)}{2}\) 次。

那只要每次算的时候加上 \(\dfrac{2}{x(x-1)}\) 不就行了?

开个 double 存答案,最后四舍五入一下就行了。精度完全没有问题的好嘛!!AC Code

ABC248F Keep Connect

场上因为写 G 没时间写这题了。。。场后胡了个 dp,明天起来补orz

ABC248G GCD cost on the tree

这不是我好早之前自己 yy 的点分治题吗.jpg

考虑点分治,对于当前根 \(\text{root}\),设 \(g_u\)\(\text{root}\to u\) 路径上点权 \(\gcd\)\(f_u\)\(u\) 的深度。

依次处理 \(\text{root}\) 的每一棵子树,并维护一个集合 \(S\)

  • 对于当前子树内的每个点 \(u\),算出 \(f_u\)\(g_u\),并将 \(\sum_{v\in S}(f_u+f_v)\gcd(g_u,g_v)\) 累计进答案。
  • 将每个点 \(u\) 插入进集合内。

现在只需要考虑如何维护集合 \(S\)

简化一下问题,我们需要维护一个集合 \(S\) ,支持加入一个数,以及对于给定的数 \(y\),查询

\[\sum_{x\in S}\gcd(x,y) \]

注意到

\[\sum_{x\in S}\gcd(x,y)=\sum_{x\in S}\sum_{d|\gcd(x,y)}\varphi(d)=\sum_{d|y }\varphi(d)\sum_{x\in S}[d|x] \]

预处理 \(\varphi\),并维护每个数在 \(S\) 中的倍数个数即可。

那么这道题也就相当于带了个权,把贡献拆成两部分就行了。

更具体地,我们要查询的东西相当于

\[\sum_{x\in S}\gcd(x,y)\cdot (f_x+f_y)=\sum_{x\in S}\sum_{d|x,d|y}\varphi(d)(f_x+f_y)=\sum_{d|y}\varphi(d)\sum_{x\in S}[d|x](f_x+f_y)\\=\sum_{d|y}\varphi(d)\left(\sum_{x\in S}[d|x]f_x+f_y\sum_{x\in S}[d|x]\right) \]

前面一部分就是带了个权,后面一部分就是不带权的情况乘上 \(f_y\)。本质上没有什么变化。

时间复杂度:我们每次加入与删除的复杂度都是 \(O(d(y))\),其中 \(d(x)\) 表示 \(x\) 的约数个数。

随便写个程序验证一下就可以发现 \(\max_{i\in[1,10^5]}d(i)=128\),所以复杂度并不会太高。

总的复杂度为 \(O(nd(V)\log n+V\log V)\),其中 \(V=10^5\) 为值域。\(V\log V\) 来自预处理约数集合。

由于 \(d(V)\) 在大多数情况下只有 \(O(\log V)\),根本卡不满 \(128\),所以常数很小。AC Code

posted @ 2022-04-16 23:31  云浅知处  阅读(379)  评论(0编辑  收藏  举报